<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 7.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.ico">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha256-wiz7ZSCn/btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.css" integrity="sha256-6cQIC71/iBIYXFK+0RHAvwmjwWzkWd+r7v/BX3/vZDc=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/green/pace-theme-minimal.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>

<script class="next-config" data-name="main" type="application/json">{"hostname":"sumumm.github.io","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.19.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"mac"},"fold":{"enable":true,"height":300},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":true,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="本文主要是STM32开发——MDK工程文件类型相关的一些相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:type" content="article">
<meta property="og:title" content="LV16-06-MDK-02-工程文件类型">
<meta property="og:url" content="https://sumumm.github.io/post/e1abea0c.html">
<meta property="og:site_name" content="苏木">
<meta property="og:description" content="本文主要是STM32开发——MDK工程文件类型相关的一些相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529195524330.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529195633353.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529195721667.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529200416215.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414222218504.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529200949898.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529201003158.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414222447760.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529201102127.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image311.jpeg">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image321.jpeg">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414225429664.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414232030451.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414232403045.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414234303798.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414233729717.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414233833843.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414234055475.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230415220024144.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230415220615175.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230415221049396.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529204130641.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230415223432834.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230410231410382.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image371.jpeg">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529205311123.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416140839500.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416140927118.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image412.jpeg">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image421.jpeg">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529200721976.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529205801781.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416143210100.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529211803575.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529213119774.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529213416563.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529210432888.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529210513865.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529210631552.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image451.jpeg">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416150518915.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416150619026.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416150742032.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image491.jpeg">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416151336450.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image511.jpeg">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230530093355921.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529223111082.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529223325533.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529223538076.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529223843189.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529224055149.png">
<meta property="article:published_time" content="2023-06-04T14:06:31.000Z">
<meta property="article:modified_time" content="2025-06-13T16:25:57.007Z">
<meta property="article:author" content="苏木">
<meta property="article:tag" content="LV16-STM32开发">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529195524330.png">


<link rel="canonical" href="https://sumumm.github.io/post/e1abea0c.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://sumumm.github.io/post/e1abea0c.html","path":"post/e1abea0c.html","title":"LV16-06-MDK-02-工程文件类型"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>LV16-06-MDK-02-工程文件类型 | 苏木</title>
  








    <script src="/js/browser_tools_disable.js"></script>

  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<!-- hexo injector head_end start --><link rel="stylesheet" href="https://unpkg.com/hexo-next-tags-plus@latest/lib/tag_plus.css" media="defer" onload="this.media='all'"><!-- hexo injector head_end end --></head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">苏木</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">我的学习之路</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>苏木的家</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类页<span class="badge">42</span></a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档页<span class="badge">673</span></a></li><li class="menu-item menu-item-flink"><a href="/flink/" rel="section"><i class="fa fa-link fa-fw"></i>友人帐</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于我</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%80%E3%80%81MDK%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B"><span class="nav-text">一、MDK工程文件类型</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E6%96%87%E4%BB%B6%E6%B1%87%E6%80%BB"><span class="nav-text">1. 文件汇总</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-1-Project%E7%9B%AE%E5%BD%95%E4%B8%8B%E7%9A%84%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6"><span class="nav-text">1.1 Project目录下的工程文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-2-%E6%BA%90%E6%96%87%E4%BB%B6"><span class="nav-text">1.2 源文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-3-Output%E7%9B%AE%E5%BD%95"><span class="nav-text">1.3 Output目录</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-4-Listing%E7%9B%AE%E5%BD%95"><span class="nav-text">1.4 Listing目录</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-Project%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6"><span class="nav-text">2. Project工程文件</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-uvprojx-%E6%96%87%E4%BB%B6"><span class="nav-text">2.1 uvprojx 文件  </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-uvoptx-%E6%96%87%E4%BB%B6"><span class="nav-text">2.2 uvoptx 文件  </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-3-uvguix-%E6%96%87%E4%BB%B6"><span class="nav-text">2.3 uvguix 文件  </span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-Output%E7%9B%AE%E5%BD%95%E4%B8%8B%E6%96%87%E4%BB%B6"><span class="nav-text">3. Output目录下文件</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-1-Output%E7%9B%AE%E5%BD%95%E4%BD%8D%E7%BD%AE%E9%80%89%E6%8B%A9"><span class="nav-text">3.1 Output目录位置选择</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-2-lib%E5%BA%93%E6%96%87%E4%BB%B6"><span class="nav-text">3.2 lib库文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-2-dep%E3%80%81d-%E4%BE%9D%E8%B5%96%E6%96%87%E4%BB%B6"><span class="nav-text">3.2 dep、d 依赖文件  </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-3-crf-%E4%BA%A4%E5%8F%89%E5%BC%95%E7%94%A8%E6%96%87%E4%BB%B6"><span class="nav-text">3.3 crf 交叉引用文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-4-o%E3%80%81axf%E6%96%87%E4%BB%B6"><span class="nav-text">3.4 o、axf文件</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-4-1-%E7%9B%AE%E6%A0%87%E6%96%87%E4%BB%B6%E8%AF%B4%E6%98%8E"><span class="nav-text">3.4.1 目标文件说明</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-4-2-o%E6%96%87%E4%BB%B6%E4%B8%8Eaxf%E6%96%87%E4%BB%B6%E7%9A%84%E5%85%B3%E7%B3%BB"><span class="nav-text">3.4.2 o文件与axf文件的关系</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-5-ELF%E6%96%87%E4%BB%B6%E5%90%84%E9%83%A8%E5%88%86%E8%AF%B4%E6%98%8E"><span class="nav-text">3.5 ELF文件各部分说明</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-5-1-ELF%E6%96%87%E4%BB%B6%E5%A4%B4"><span class="nav-text">3.5.1 ELF文件头</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#3-5-1-1-%E7%94%9F%E6%88%90elf%E4%BF%A1%E6%81%AF"><span class="nav-text">3.5.1.1 生成elf信息</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#3-5-1-2-%E5%86%85%E5%AE%B9%E5%88%86%E6%9E%90"><span class="nav-text">3.5.1.2 内容分析</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-5-2-%E7%A8%8B%E5%BA%8F%E5%A4%B4"><span class="nav-text">3.5.2 程序头</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-5-2-%E8%8A%82%E5%8C%BA%E5%A4%B4"><span class="nav-text">3.5.2 节区头</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-5-3-%E8%8A%82%E5%8C%BA%E4%B8%BB%E4%BD%93%E5%8F%8A%E5%8F%8D%E6%B1%87%E7%BC%96%E4%BB%A3%E7%A0%81"><span class="nav-text">3.5.3 节区主体及反汇编代码</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-5-4-%E5%88%86%E6%95%A3%E5%8A%A0%E8%BD%BD%E4%BB%A3%E7%A0%81"><span class="nav-text">3.5.4 分散加载代码</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-6-hex%E6%96%87%E4%BB%B6%E5%8F%8Abin%E6%96%87%E4%BB%B6"><span class="nav-text">3.6 hex文件及bin文件</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-6-1-%E7%94%9F%E6%88%90hex%E6%96%87%E4%BB%B6"><span class="nav-text">3.6.1 生成hex文件</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-6-2-%E7%94%9F%E6%88%90bin%E6%96%87%E4%BB%B6"><span class="nav-text">3.6.2 生成bin文件</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-6-3-hex%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F"><span class="nav-text">3.6.3 hex文件格式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-6-4-hex%E3%80%81bin%E5%8F%8Aaxf%E6%96%87%E4%BB%B6%E7%9A%84%E5%8C%BA%E5%88%AB%E4%B8%8E%E8%81%94%E7%B3%BB"><span class="nav-text">3.6.4 hex、bin及axf文件的区别与联系</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-7-%E6%80%BB%E7%BB%93"><span class="nav-text">3.7 总结</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-Listing%E7%9B%AE%E5%BD%95%E4%B8%8B%E6%96%87%E4%BB%B6"><span class="nav-text">4. Listing目录下文件</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#4-1-Listing%E7%9B%AE%E5%BD%95%E4%BD%8D%E7%BD%AE%E9%80%89%E6%8B%A9"><span class="nav-text">4.1 Listing目录位置选择</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-2-%E6%89%93%E5%BC%80map%E6%96%87%E4%BB%B6"><span class="nav-text">4.2 打开map文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-3-map%E6%96%87%E4%BB%B6%E8%AF%B4%E6%98%8E"><span class="nav-text">4.3 map文件说明</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-1-%E8%8A%82%E5%8C%BA%E7%9A%84%E8%B7%A8%E6%96%87%E4%BB%B6%E5%BC%95%E7%94%A8"><span class="nav-text">4.3.1 节区的跨文件引用</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-2-%E5%88%A0%E9%99%A4%E6%97%A0%E7%94%A8%E8%8A%82%E5%8C%BA"><span class="nav-text">4.3.2 删除无用节区</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-3-%E7%AC%A6%E5%8F%B7%E6%98%A0%E5%83%8F%E8%A1%A8"><span class="nav-text">4.3.3 符号映像表</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-4-%E5%AD%98%E5%82%A8%E5%99%A8%E6%98%A0%E5%83%8F%E7%B4%A2%E5%BC%95"><span class="nav-text">4.3.4 存储器映像索引</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-5-%E6%98%A0%E5%83%8F%E7%BB%84%E4%BB%B6%E5%A4%A7%E5%B0%8F"><span class="nav-text">4.3.5 映像组件大小</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3-6-%E6%80%BB%E7%BB%93"><span class="nav-text">4.3.6 总结</span></a></li></ol></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%8C%E3%80%81SCT%E5%88%86%E6%95%A3%E5%8A%A0%E8%BD%BD%E6%96%87%E4%BB%B6"><span class="nav-text">二、SCT分散加载文件</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-sct%E5%88%86%E6%95%A3%E5%8A%A0%E8%BD%BD%E6%96%87%E4%BB%B6%E7%AE%80%E4%BB%8B"><span class="nav-text">1. sct分散加载文件简介</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E5%88%86%E6%95%A3%E5%8A%A0%E8%BD%BD%E6%96%87%E4%BB%B6%E7%9A%84%E6%A0%BC%E5%BC%8F"><span class="nav-text">2. 分散加载文件的格式</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E"><span class="nav-text">2.1 格式说明</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-%E5%8A%A0%E8%BD%BD%E5%9F%9F"><span class="nav-text">2.2 加载域</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-3-%E6%89%A7%E8%A1%8C%E5%9F%9F"><span class="nav-text">2.3 执行域</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-4-%E8%BE%93%E5%85%A5%E8%8A%82%E5%8C%BA%E6%8F%8F%E8%BF%B0"><span class="nav-text">2.4 输入节区描述</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E9%80%9A%E8%BF%87MDK%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9%E6%9D%A5%E4%BF%AE%E6%94%B9sct%E6%96%87%E4%BB%B6"><span class="nav-text">3. 通过MDK配置选项来修改sct文件</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-1-%E9%80%89%E6%8B%A9sct%E6%96%87%E4%BB%B6%E7%9A%84%E4%BA%A7%E7%94%9F%E6%96%B9%E5%BC%8F"><span class="nav-text">3.1 选择sct文件的产生方式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-2-%E9%80%9A%E8%BF%87Target%E5%AF%B9%E8%AF%9D%E6%A1%86%E6%8E%A7%E5%88%B6%E5%AD%98%E5%82%A8%E5%99%A8%E5%88%86%E9%85%8D"><span class="nav-text">3.2 通过Target对话框控制存储器分配</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-3-%E6%8E%A7%E5%88%B6%E6%96%87%E4%BB%B6%E5%88%86%E9%85%8D%E5%88%B0%E6%8C%87%E5%AE%9A%E7%9A%84%E5%AD%98%E5%82%A8%E7%A9%BA%E9%97%B4"><span class="nav-text">3.3 控制文件分配到指定的存储空间</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-3-1-%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4"><span class="nav-text">3.3.1 操作步骤</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-3-2-%E4%B8%80%E4%B8%AA%E5%AE%9E%E4%BE%8B"><span class="nav-text">3.3.2 一个实例</span></a></li></ol></li></ol></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="苏木"
      src="/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">苏木</p>
  <div class="site-description" itemprop="description">莫道桑榆晚，为霞尚满天</div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">673</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">42</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">43</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="links-of-author animated">
      <span class="links-of-author-item">
        <a href="https://github.com/sumumm" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;sumumm" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
  </div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://sumumm.github.io/post/e1abea0c.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.jpg">
      <meta itemprop="name" content="苏木">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="苏木">
      <meta itemprop="description" content="莫道桑榆晚，为霞尚满天">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="LV16-06-MDK-02-工程文件类型 | 苏木">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          LV16-06-MDK-02-工程文件类型
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2023-06-04 22:06:31" itemprop="dateCreated datePublished" datetime="2023-06-04T22:06:31+08:00">2023-06-04</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">嵌入式开发</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/" itemprop="url" rel="index"><span itemprop="name">01HQ课程体系</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">LV16-STM32开发</span></a>
        </span>
    </span>

  
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>23k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>1:25</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><p>本文主要是STM32开发——MDK工程文件类型相关的一些相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。</p>
<span id="more"></span>

<!-- Photo: https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/ -->

<details class="folding-tag" blue><summary> 点击查看使用工具及版本 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center" width=150px>Windows</td>        <td align="left">windows11</td>    </tr>    <tr>        <td align="center">Ubuntu</td>        <td align="left">Ubuntu16.04的64位版本</td>      </tr>    <tr>        <td align="center">VMware® Workstation 16 Pro</td>        <td align="left">16.2.3 build-19376536</td>      </tr>    <tr>        <td align="center">SecureCRT</td>        <td align="left">Version 8.7.2 (x64 build 2214)   -   正式版-2020年5月14日</td>      </tr>    <tr>        <td align="center">开发板</td>        <td align="left">正点原子 i.MX6ULL Linux阿尔法开发板</td>      </tr>    <tr>        <td align="center">uboot</td>        <td align="left">NXP官方提供的uboot，NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)</td>      </tr>    <tr>        <td align="center">linux内核</td>        <td align="left">linux-4.15(NXP官方提供)</td>      </tr>    <tr>        <td align="center">STM32开发板</td>        <td align="left">正点原子战舰V3(STM32F103ZET6)</td>      </tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看本文参考资料 </summary>
              <div class='content'>
              <ul><li>通用</li></ul><table><tr><td align="center">分类  </td><td align="center">网址</td><td align="center">说明</td></tr><tr><td align="center" rowspan="4">官方网站</td><td align="left"><a href="https://www.arm.com/" target="_blank">https://www.arm.com/</a></td><td align="left">ARM官方网站，在这里我们可以找到Cotex-Mx以及ARMVx的一些文档</td></tr><tr>                                            <td align="left"><a href="https://www.st.com/content/st_com/zh.html" target="_blank">https://www.st.com/content/st_com/zh.html</a></td><td align="left">ST官方网站，在这里我们可以找到STM32的相关文档</td></tr><tr>                                            <td align="left"><a href="https://www.stmcu.com.cn/" target="_blank">https://www.stmcu.com.cn/</a></td><td align="left">意法半导体ST中文官方网站，在这里我们可以找到STM32的相关中文参考文档</td></tr><tr>                                            <td align="left"><a href="http://elm-chan.org/fsw/ff/00index_e.html" target="_blank">http://elm-chan.org/fsw/ff/00index_e.html</a></td><td align="left">FatFs文件系统官网</td></tr><tr><td align="center" rowspan="3">教程书籍</td><td align="left"><a href="STM32开发相关资料/01ARM参考资料/ARM Cortex-M3权威指南(中文).pdf" target="_blank">《ARM Cortex-M3权威指南》</a></td><td alirn="left" rowspan="3">ARM公司专家Joseph Yiu（姚文祥）的力作，中文翻译是NXP的宋岩</td></tr><tr>                                            <td align="left"><a href="STM32开发相关资料/01ARM参考资料/ARM Cortex-M0权威指南(中文).pdf" target="_blank">《ARM Cortex-M0权威指南》</a></td></tr><tr>                                            <td align="left"><a href="" target="_blank">《ARM Cortex-M3与Cortex-M4权威指南》</a></td></tr><tr><td align="center" rowspan="4">开发论坛</td><td align="left"><a href="http://47.111.11.73/forum.php" target="_blank">http://47.111.11.73/forum.php</a></td><td align="left">开源电子网，正点原子的资料下载及问题讨论论坛</td></tr><tr>                                            <td align="left"><a href="https://www.firebbs.cn/forum.php" target="_blank">https://www.firebbs.cn/forum.php</a></td><td align="left">国内Kinetis开发板-野火/秉火（刘火良）主持的论坛，现也做STM32和i.MX RT</td></tr><tr>                                            <td align="left"><a href="https://www.amobbs.com/index.php" target="_blank">https://www.amobbs.com/index.php</a></td><td align="left">阿莫（莫进明）主持的论坛，号称国内最早最火的电子论坛，以交流Atmel AVR系列单片机起家，现已拓展到嵌入式全平台，其STM32系列帖子有70W+。</td></tr><tr>                                            <td align="left"><a href="http://download.100ask.net/index.html" target="_blank">http://download.100ask.net/index.html</a></td><td align="left">韦东山嵌入式资料中心，有些STM32和linux的相关资料也可以来这里找。</td></tr><tr><td align="center" rowspan="3">博客参考</td><td align="left"><a href="http://www.openedv.com/" target="_blank">http://www.openedv.com/</a></td><td align="left">开源网-原子哥个人博客</td></tr><tr>                                            <td align="left"><a href="http://blog.chinaaet.com/jihceng0622" target="_blank">http://blog.chinaaet.com/jihceng0622</a></td><td align="left">博主是原Freescale现NXP的现场应用工程师</td></tr><tr>                                            <td align="left"><a href="https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/cortex-m-resources" target="_blank">cortex-m-resources</a></td><td align="left">这其实并不算是一个博客，这是ARM公司专家Joseph Yiu收集整理的所有对开发者有用的官方Cortex-M资料链接（也包含极少数外部资源链接）</td></tr></table><ul><li>STM32</li></ul><table>    <tr><td align="center" rowspan="2">STM32</td><td align="left"><a href="https://doc.embedfire.com/mcu/stm32/f103/hal_general/zh/latest/index.html" target="_blank">STM32 HAL库开发实战指南——基于F103系列开发板</a></td><td align="left">野火STM32开发教程在线文档</td></tr><tr>                                            <td align="left"><a href="https://doc.embedfire.com/mcu/stm32/f103badao/std/zh/latest/index.html" target="_blank">STM32库开发实战指南——基于野火霸道开发板</a></td><td align="left">野火STM32开发教程在线文档</td></tr></table><ul><li>SD卡</li></ul><table>    <tr><td align="left"><a href="https://www.sdcard.org/" target="_blank">SD Association</a></td><td align="left">提供了SD存储卡和SDIO卡系统规范</td></tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看相关文件下载 </summary>
              <div class='content'>
              <table>    <tr><td align="left"><a href="https://www.st.com/resource/en/datasheet/stm32f103ze.pdf" target="_blank">STM32F103xx英文数据手册</a></td><td align="left">STM32F103xC/D/E系列的英文数据手册</td></tr>    <tr><td align="left"><a href="https://www.stmcu.com.cn/Designresource/detail/localization_document%20/709978" target="_blank">STM32F103xx中文数据手册</a></td><td align="left">STM32F103xC/D/E系列的中文数据手册</td></tr>    <tr><td align="left"><a href="https://www.st.com/resource/en/reference_manual/rm0008-stm32f101xx-stm32f102xx-stm32f103xx-stm32f105xx-and-stm32f107xx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf" target="_blank">STM32F10xxx英文参考手册（RM0008）</a></td><td align="left">STM32F10xxx系列的英文参考手册</td></tr>    <tr><td align="left"><a href="https://www.stmcu.com.cn/Designresource/detail/localization_document%20/710001" target="_blank">STM32F10xxx中文参考手册（RM0008）</a></td><td align="left">STM32F10xxx系列的中文参考手册</td></tr>    <tr><td align="left"><a href="https://developer.arm.com/documentation/100165/0201/?lang=en" target="_blank">Arm Cortex-M3 处理器技术参考手册-英文版</a></td><td align="left">Cortex-M3技术参考手册-英文版</td></tr>    <tr><td align="left"><a href="https://www.st.com/resource/en/programming_manual/pm0056-stm32f10xxx20xxx21xxxl1xxxx-cortexm3-programming-manual-stmicroelectronics.pdf" target="_blank">STM32F10xxx Cortex-M3编程手册-英文版(PM0056)</a></td><td align="left">STM32F10xxx/20xxx/21xxx/L1xxxx系列Cortex-M3编程手册-英文版</td></tr>    <tr><td align="left"><a href="https://www.sdcard.org/downloads/pls/" target="_blank">SD卡相关资料——最新版本</a></td><td align="left">有关SD卡的一些资料可以从这里下载</td></tr>    <tr><td align="left"><a href="https://www.sdcard.org/downloads/pls/archives/" target="_blank">SD卡相关资料——历史版本</a></td><td align="left">有关SD卡的一些历史版本资料可以从这里下载，比如后边看的SD卡2.0协议</td></tr>    <tr><td align="left"><a href="./" target="_blank">SD 2.0 协议标准完整版</a></td><td align="left">这是一篇关于SD卡2.0协议的中文文档，还是比较有参考价值的，可以一看</td></tr></table>
              </div>
            </details> 

<p>本篇笔记主要是参考的野火的文档。使用的工程呢可以去这里下载：<a target="_blank" rel="noopener" href="https://gitee.com/Embedfire-stm32f103-badao/ebf_stm32f103_badao_std_code">ebf_stm32f103_badao_std_code: 野火STM32F103 霸道开发板 标准库教程配套代码 (gitee.com)</a></p>
<h1 id="一、MDK工程文件类型"><a href="#一、MDK工程文件类型" class="headerlink" title="一、MDK工程文件类型"></a><font size=3>一、MDK工程文件类型</font></h1><h2 id="1-文件汇总"><a href="#1-文件汇总" class="headerlink" title="1. 文件汇总"></a><font size=3>1. 文件汇总</font></h2><h3 id="1-1-Project目录下的工程文件"><a href="#1-1-Project目录下的工程文件" class="headerlink" title="1.1 Project目录下的工程文件"></a><font size=3>1.1 Project目录下的工程文件</font></h3><table>
    <tr><td align="left">后缀</td><td align="left">说明</td></tr>
    <tr><td align="left">*.uvguix</td><td align="left">MDK5工程的窗口布局文件，在MDK4中*.UVGUI后缀的文件功能相同</td></tr>
    <tr><td align="left">*.uvprojx</td><td align="left">MDK5的工程文件，它使用了XML格式记录了工程结构，双击它可以打开整个工程，在MDK4中*.UVPROJ后缀的文件功能相同</td></tr>
    <tr><td align="left">*.uvoptx</td><td align="left">MDK5的工程配置选项，包含debugger、trace configuration、breakpooints以及当前打开的文件，在MDK4中*.UVOPT后缀的文件功能相同</td></tr>
    <tr><td align="left">*.ini</td><td align="left">某些下载器的配置记录文件</td></tr>
</table>

<h3 id="1-2-源文件"><a href="#1-2-源文件" class="headerlink" title="1.2 源文件"></a><font size=3>1.2 源文件</font></h3><table>
    <tr><td align="left">后缀</td><td align="left">说明</td></tr>
    <tr><td align="left">*.c</td><td align="left">C语言源文件</td></tr>
    <tr><td align="left">*.cpp</td><td align="left">C++语言源文件</td></tr>
    <tr><td align="left">*.h</td><td align="left">C/C++的头文件</td></tr>
    <tr><td align="left">*.s</td><td align="left">汇编语言的源文件</td></tr>
    <tr><td align="left">*.inc</td><td align="left">汇编语言的头文件(使用“$include”来包含)</td></tr>
</table>

<h3 id="1-3-Output目录"><a href="#1-3-Output目录" class="headerlink" title="1.3 Output目录"></a><font size=3>1.3 Output目录</font></h3><table>
    <tr><td align="left">后缀</td><td align="left">说明</td></tr>
    <tr><td align="left">*.dep</td><td align="left">整个工程的依赖文件</td></tr>
    <tr><td align="left">*.d</td><td align="left">描述了对应.o的依赖的文件</td></tr>
    <tr><td align="left">*.crf</td><td align="left">交叉引用文件，包含了浏览信息(定义、引用及标识符)</td></tr>
    <tr><td align="left">*.o</td><td align="left">可重定位的对象文件(目标文件)</td></tr>
    <tr><td align="left">*.bin</td><td align="left">二进制格式的映像文件，是纯粹的FLASH映像，不含任何额外信息</td></tr>
    <tr><td align="left">*.hex</td><td align="left">Intel Hex格式的映像文件，可理解为带存储地址描述格式的bin文件 </td></tr>
    <tr><td align="left">*.elf</td><td align="left">由GCC编译生成的文件，功能跟axf文件一样，该文件不可重定位</td></tr>
    <tr><td align="left">*.axf</td><td align="left">由ARMCC编译生成的可执行对象文件，可用于调试，该文件不可重定位</td></tr>
    <tr><td align="left">*.sct</td><td align="left">链接器控制文件(分散加载)</td></tr>
    <tr><td align="left">*.scr</td><td align="left">链接器产生的分散加载文件</td></tr>
    <tr><td align="left">*.lnp</td><td align="left">MDK生成的链接输入文件，用于调用链接器时的命令输入</td></tr>
    <tr><td align="left">*.htm</td><td align="left">链接器生成的静态调用图文件</td></tr>
    <tr><td align="left">*.build_log.htm</td><td align="left">构建工程的日志记录文件</td></tr>
</table>

<h3 id="1-4-Listing目录"><a href="#1-4-Listing目录" class="headerlink" title="1.4 Listing目录"></a><font size=3>1.4 Listing目录</font></h3><table>
    <tr><td align="left">后缀</td><td align="left">说明</td></tr>
    <tr><td align="left">*.lst</td><td align="left">C及汇编编译器产生的列表文件</td></tr>
    <tr><td align="left">*.map</td><td align="left">链接器生成的列表文件，包含存储器映像分布</td></tr>
    <tr><td align="left">*.ini</td><td align="left">仿真、下载器的脚本文件</td></tr>
    <tr><td align="left">其它</td><td align="left"></td></tr>
</table>


<p>上边就是一些相关文件的后缀名和大概的说明，这里就一一说明了，挑几个可能会用到的说明一下。</p>
<h2 id="2-Project工程文件"><a href="#2-Project工程文件" class="headerlink" title="2. Project工程文件"></a><font size=3>2. Project工程文件</font></h2><p>uvprojx、 uvoptx 及 uvguix 都是使用 XML 格式记录的文件，若使用记事本打开可以看到 XML 代码。而当使用 MDK 软件打开时，它根据这些文件的 XML 记录加载工程的各种参数，使得我们每次重新打开工程时，都能恢复上一次的工作环境。</p>
<p>这些工程参数都是当 MDK 正常退出时才会被写入保存，所以若 MDK 错误退出时 (如使用 Windows 的任务管理器强制关闭)，工程配置参数的最新更改是不会被记录的，重新打开工程时要再次配置。其中 uvprojx 文件是最重要的，删掉它我们就无法再正常打开工程了，而 uvoptx 及 uvguix 文件并不是必须的，可以删除，重新使用 MDK 打开 uvprojx工程文件后，会以默认参数重新创建 uvoptx 及 uvguix 文件。 (所以当使用 Git&#x2F;SVN 等代码管理的时候，往往只保留 uvprojx 文件)    </p>
<h3 id="2-1-uvprojx-文件"><a href="#2-1-uvprojx-文件" class="headerlink" title="2.1 uvprojx 文件  "></a><font size=3>2.1 uvprojx 文件  </font></h3><p>uvprojx 文件就是我们平时双击打开的工程文件，它记录了整个工程的结构，如芯片类型、工程包含了哪些源文件等内容 。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529195524330.png" alt="image-20230529195524330" style="zoom:45%;" />

<h3 id="2-2-uvoptx-文件"><a href="#2-2-uvoptx-文件" class="headerlink" title="2.2 uvoptx 文件  "></a><font size=3>2.2 uvoptx 文件  </font></h3><p>uvoptx 文件记录了工程的配置选项，如下载器的类型、变量跟踪配置、断点位置以及当前已打开的文件等等 。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529195633353.png" alt="image-20230529195633353" style="zoom: 33%;" />

<h3 id="2-3-uvguix-文件"><a href="#2-3-uvguix-文件" class="headerlink" title="2.3 uvguix 文件  "></a><font size=3>2.3 uvguix 文件  </font></h3><p>uvguix 文件记录了 MDK 软件的 GUI 布局，如代码编辑区窗口的大小、编译输出提示窗口的位置等等。  </p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529195721667.png" alt="image-20230529195721667" style="zoom:45%;" />

<h2 id="3-Output目录下文件"><a href="#3-Output目录下文件" class="headerlink" title="3. Output目录下文件"></a><font size=3>3. Output目录下文件</font></h2><h3 id="3-1-Output目录位置选择"><a href="#3-1-Output目录位置选择" class="headerlink" title="3.1 Output目录位置选择"></a><font size=3>3.1 Output目录位置选择</font></h3><p>Output目录是存放输出文件以及一些中间文件的目录，这个目录是可以配置的：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529200416215.png" alt="image-20230529200416215" style="zoom:33%;" />

<p>点击 MDK 中的编译按钮，它会根据工程的配置及工程中的源文件输出各种对象和列表文件，在工程的“【Options for Targe】&rarr;【Output】&rarr;【Select Folder for Objects】”中配置输出目录的位置。</p>
<h3 id="3-2-lib库文件"><a href="#3-2-lib库文件" class="headerlink" title="3.2 lib库文件"></a><font size=3>3.2 lib库文件</font></h3><p>上边好像没有列出，但是可能会用到。在某些情况，我们希望提供给第三方一个可用的代码库，但不希望对方看到源码，这个时候我们就可以把工程生成lib文件(Library file)提供给对方，在MDK中可配置【Options for Target】&rarr;【Create Library】选项把工程编译成库文件，</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414222218504.png" alt="image-20230414222218504" style="zoom: 33%;" />

<p>工程中生成可执行文件或库文件只能二选一，默认编译是生成可执行文件的，可执行文件即我们下载到芯片上直接运行的机器码。得到生成的*.lib文件后，可把它像C文件一样添加到其它工程中，并在该工程调用lib提供的函数接口，除了不能看到*.lib文件的源码，在应用方面它跟C源文件没有区别。</p>
<h3 id="3-2-dep、d-依赖文件"><a href="#3-2-dep、d-依赖文件" class="headerlink" title="3.2 dep、d 依赖文件  "></a><font size=3>3.2 dep、d 依赖文件  </font></h3><p>*.dep 和 *.d 文件 (Dependency file) 记录的是工程或其它文件的依赖，主要记录了引用的头文件路径，其中 *.dep 是整个工程的依赖，它以工程名命名，而*.d 是单个源文件的依赖，它们以对应的源文件名命名。这些记录使用文本格式存储，我们可直接使用记事本打开，见图工程的 dep 文件内容：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529200949898.png" alt="image-20230529200949898" style="zoom:50%;" />

<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529201003158.png" alt="image-20230529201003158" style="zoom:50%;" />



<h3 id="3-3-crf-交叉引用文件"><a href="#3-3-crf-交叉引用文件" class="headerlink" title="3.3 crf 交叉引用文件"></a><font size=3>3.3 crf 交叉引用文件</font></h3><p>*.crf是交叉引用文件(Cross-Reference file)，它主要包含了浏览信息(browse information)，即源代码中的宏定义、变量及函数的定义和声明的位置。我们在代码编辑器中点击【Go To Definition Of ‘xxxx’】可实现浏览跳转，跳转的时候，MDK就是通过 *.crf 文件<strong>查找出跳转位置</strong>的。</p>
<p>通过配置MDK中的【Option for Target】&rarr;【Output】&rarr;【Browse Information】选项可以设置编译时是否生成浏览信息。注意只有勾选该选项并编译后，才能实现函数定义，宏定义这些浏览跳转功能。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414222447760.png" alt="image-20230414222447760" style="zoom: 33%;" />

<p>跳转操作如下图：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529201102127.png" alt="image-20230529201102127" style="zoom:50%;" />

<p>*.crf 文件使用了特定的格式表示，直接用文本编辑器打开会看到大部分乱码 ，文件内容的话，这里就不再深究了。</p>
<h3 id="3-4-o、axf文件"><a href="#3-4-o、axf文件" class="headerlink" title="3.4 o、axf文件"></a><font size=3>3.4 o、axf文件</font></h3><p>*.o、*.elf、*.axf、*.bin及*.hex文件都存储了编译器根据源代码生成的机器码，根据应用场合的不同，它们又有所区别。但是我看到MDK的输出目录中其实并没有*.elf文件，这里也放在一起学习一下吧。</p>
<h4 id="3-4-1-目标文件说明"><a href="#3-4-1-目标文件说明" class="headerlink" title="3.4.1 目标文件说明"></a><font size=3>3.4.1 目标文件说明</font></h4><p>*.o、*.elf、*.axf以及前面提到的lib文件都是属于目标文件，它们都是使用ELF格式来存储的，关于ELF格式的详细内容，我还没有深究，后边需要学习的话再补充吧，这里简单说明一下，详细的可以看这里(本地文档：<a href="./STM32%E5%BC%80%E5%8F%91%E7%9B%B8%E5%85%B3%E8%B5%84%E6%96%99/03MDK/ELF%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F.pdf">ELF文件格式.pdf</a>)。</p>
<p>ELF是Executable and Linking Format的缩写，译为可执行链接格式，该格式用于记录目标文件的内容。在Linux及Windows系统下都有使用该格式的文件(或类似格式)用于记录应用程序的内容，告诉操作系统如何链接、加载及执行该应用程序。</p>
<p>目标文件主要有如下三种类型：</p>
<p>（1）可重定位的文件(Relocatable File)，包含基础代码和数据，但它的代码及数据都没有指定绝对地址，因此它适合于与其他目标文件链接来创建可执行文件或者共享目标文件。 这种文件一般由编译器根据源代码生成。例如MDK的armcc和armasm生成的*.o文件就是这一类，另外还有Linux的*.o 文件，Windows的 *.obj文件。</p>
<p>（2）可执行文件(Executable File) ，它包含适合于执行的程序，它内部组织的代码数据都有固定的地址(或相对于基地址的偏移)，系统可根据这些地址信息把程序加载到内存执行。这种文件一般由链接器根据可重定位文件链接而成，它主要是组织各个可重定位文件，给它们的代码及数据一一打上地址标号，固定其在程序内部的位置，链接后，程序内部各种代码及数据段不可再重定位(即不能再参与链接器的链接)。</p>
<p>例如MDK的armlink生成的*.elf及*.axf文件，(使用gcc编译工具可生成*.elf文件，用armlink生成的是*.axf文件，*.axf文件在*.elf之外，增加了调试使用的信息，其余区别不大，后面我们仅讲解*.axf文件)，另外还有Linux的&#x2F;bin&#x2F;bash文件，Windows的*.exe文件。</p>
<p>（3）共享目标文件(Shared Object File)， 它的定义比较难理解，我们直接举例，MDK生成的*.lib文件就属于共享目标文件，它可以继续参与链接，加入到可执行文件之中。另外，Linux的 .so ，如&#x2F;lib&#x2F; glibc-2.5.so，Windows的DLL都属于这一类。</p>
<h4 id="3-4-2-o文件与axf文件的关系"><a href="#3-4-2-o文件与axf文件的关系" class="headerlink" title="3.4.2 o文件与axf文件的关系"></a><font size=3>3.4.2 o文件与axf文件的关系</font></h4><p>*.axf文件是由多个*.o文件链接而成的，而*.o文件由相应的源文件编译而成，一个源文件对应一个*.o文件。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image311.jpeg" alt="image311.jpeg" style="zoom:50%;" />

<p>图中的中间代表的是 armlink 链接器，在它的右侧是输入链接器的*.o文件，左侧是它输出的*.axf文件。可以看到，由于都使用ELF文件格式，*.o与*.axf文件的结构是类似的，它们包含ELF文件头、程序头、节区(section)以及节区头部表。各个部分的功能说明如下：</p>
<table>
    <tr><td align="left" width="110">ELF文件头</td><td align="left">用来描述整个文件的组织，例如数据的大小端格式，程序头、节区头在文件中的位置等。</td></tr>
    <tr><td align="left">程序头   </td><td align="left">告诉系统如何加载程序，例如程序主体存储在本文件的哪个位置，程序的大小，程序要加载到内存什么地址等等。 MDK的可重定位文件*.o不包含这部分内容，因为它还不是可执行文件，而armlink输出的*.axf文件就包含该内容了。</td></tr>
    <tr><td align="left">节区     </td><td align="left">是*.o文件的独立数据区域，它包含提供给链接视图使用的大量信息，如指令(Code)、数据(RO、RW、ZI-data)、 符号表(函数、变量名等)、重定位信息等，例如每个由C语言定义的函数在*.o文件中都会有一个独立的节区。</td></tr>
    <tr><td align="left">节区头   </td><td align="left">存储在最后，包含了本文件节区的信息，如节区名称、大小等等。</td></tr>
</table>

<p>总的来说，链接器把各个*.o文件的节区归类、排列，根据目标器件的情况编排地址生成输出，汇总到*.axf文件。例如，“流水灯”工程中在“bsp_led.c”文件中有一个LED_GPIO_Config函数，而它内部调用了“stm32f1xx_hal_gpio.c”的GPIO_Init函数，经过 armcc 编译后，LED_GPIO_Config 及 GPIO_Iint 函数都成了指令代码，分别存储在 bsp_led.o 及 stm32f1xx_hal_gpio.o 文件中，这些指令在*.o文件都没有指定地址，仅包含了内容、大小以及调用的链接信息，而经过链接器后，链接器给它们都分配了特定的地址，并且把地址根据调用指向链接起来。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image321.jpeg" alt="image321.jpeg" style="zoom:50%;" />

<h3 id="3-5-ELF文件各部分说明"><a href="#3-5-ELF文件各部分说明" class="headerlink" title="3.5 ELF文件各部分说明"></a><font size=3>3.5 ELF文件各部分说明</font></h3><p>前边知道*.o和*.axf文件都是ELF格式的，它包含ELF文件头、程序头、节区(section)以及节区头部表，这一部分我们来看一下各部分的说明。</p>
<h4 id="3-5-1-ELF文件头"><a href="#3-5-1-ELF文件头" class="headerlink" title="3.5.1 ELF文件头"></a><font size=3>3.5.1 ELF文件头</font></h4><h5 id="3-5-1-1-生成elf信息"><a href="#3-5-1-1-生成elf信息" class="headerlink" title="3.5.1.1 生成elf信息"></a><font size=3>3.5.1.1 生成elf信息</font></h5><p>接下来我们看看具体文件的内容，使用fromelf文件可以查看*.o、*.axf及*.lib文件的ELF信息。使用命令行，切换到文件所在的目录，输入“fromelf –text –v file_name.o”命令，可控制输出file_name.o的详细信息。这一部分会用到野火的相关例程，可以去这里下载：<a target="_blank" rel="noopener" href="https://gitee.com/Embedfire-stm32f103-badao/ebf_stm32f103_badao_std_code">ebf_stm32f103_badao_std_code: 野火STM32F103 霸道开发板 标准库教程配套代码 (gitee.com)</a></p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414225429664.png" alt="image-20230414225429664" style="zoom:50%;" />

<p>然后我们打开文件然后解压，进入程序目录，我么可以这样（原来win11下多了一个叫终端的东西，可以通过终端选择是powershell还是命令提示符）：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414232030451.png" alt="image-20230414232030451" style="zoom:33%;" />

<p>然后就会打开powershell，并且处于这个目录下：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414232403045.png" alt="image-20230414232403045" style="zoom:33%;" />

<p>fromelf –text命令还有一些参数，我们使用这些选项来生成对应的文件，我们来了解一下：</p>
<table>
<thead>
<tr>
<th>fromelf选项</th>
<th>可查看的信息</th>
<th>生成到相应的文件</th>
</tr>
</thead>
<tbody><tr>
<td>-v</td>
<td>详细信息</td>
<td>bsp_led_o_elfInfo_v.txt</td>
</tr>
<tr>
<td>-a</td>
<td>数据的地址</td>
<td>bsp_led_o_elfInfo_a.txt</td>
</tr>
<tr>
<td>-c</td>
<td>反汇编代码</td>
<td>bsp_led_o_elfInfo_c.txt</td>
</tr>
<tr>
<td>-d</td>
<td>data section的内容</td>
<td>bsp_led_o_elfInfo_d.txt</td>
</tr>
<tr>
<td>-e</td>
<td>异常表</td>
<td>bsp_led_o_elfInfo_e.txt</td>
</tr>
<tr>
<td>-g</td>
<td>调试表</td>
<td>bsp_led_o_elfInfo_g.txt</td>
</tr>
<tr>
<td>-r</td>
<td>重定位信息</td>
<td>bsp_led_o_elfInfo_r.txt</td>
</tr>
<tr>
<td>-s</td>
<td>符号表</td>
<td>bsp_led_o_elfInfo_s.txt</td>
</tr>
<tr>
<td>-t</td>
<td>字符串表</td>
<td>bsp_led_o_elfInfo_t.txt</td>
</tr>
<tr>
<td>-y</td>
<td>动态段内容</td>
<td>bsp_led_o_elfInfo_y.txt</td>
</tr>
<tr>
<td>-z</td>
<td>代码及数据的大小信息</td>
<td>bsp_led_o_elfInfo_z.txt</td>
</tr>
</tbody></table>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">放在 bsp_led.o 目录下，命名为1.ps1</span></span><br><span class="line">fromelf --text -v bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_v.txt</span><br><span class="line">fromelf --text -a bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_a.txt</span><br><span class="line">fromelf --text -c bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_c.txt</span><br><span class="line">fromelf --text -d bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_d.txt</span><br><span class="line">fromelf --text -e bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_e.txt</span><br><span class="line">fromelf --text -g bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_g.txt</span><br><span class="line">fromelf --text -r bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_r.txt</span><br><span class="line">fromelf --text -s bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_s.txt</span><br><span class="line">fromelf --text -t bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_t.txt</span><br><span class="line">fromelf --text -y bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_y.txt</span><br><span class="line">fromelf --text -z bsp_led.o --output ../elfInfo/bsp_led_o_elfInfo_z.txt</span><br></pre></td></tr></table></figure>

<p>我们运行这个脚本：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">PS D:\MyLinux\Ubuntu\Sharedfiles\3Linux\16-LV16\ebf_stm32f103_badao_std_code-master\46-MDK编译过程及文件全解\程序\MDK文 件详解-GPIO输出—多彩流水灯\Output&gt; .\1.ps1</span><br></pre></td></tr></table></figure>

<p>然后就可以在上一级目录下自动创建elfInfo文件夹，并在此文件夹下生成上边那些文件。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414234303798.png" alt="image-20230414234303798" style="zoom: 33%;" />

<details class="folding-tag" blue><summary> 无法运行脚本？ </summary>
              <div class='content'>
              <p>我们像linux一样运行脚本时，报这个？</p><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414233729717.png" alt="image-20230414233729717" style="zoom: 33%;" /><p>计算机上启动 Windows PowerShell 时，执行策略很可能是 Restricted（默认设置）。Restricted 执行策略不允许任何脚本运行。 AllSigned 和 RemoteSigned 执行策略可防止 Windows PowerShell 运行没有数字签名的脚本。我们使用下边的命令确认：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">get-executionpolicy</span><br></pre></td></tr></table></figure><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414233833843.png" alt="image-20230414233833843" style="zoom: 33%;" /><p>发现果然是这样，然后我们以管理员身份运行powershell并输入以下命令，并输入Y即可：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">set-executionpolicy remotesigned</span><br></pre></td></tr></table></figure><img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230414234055475.png" alt="image-20230414234055475" style="zoom: 33%;" />
              </div>
            </details>

<h5 id="3-5-1-2-内容分析"><a href="#3-5-1-2-内容分析" class="headerlink" title="3.5.1.2 内容分析"></a><font size=3>3.5.1.2 内容分析</font></h5><p>我们打开 bsp_led_o_elfInfo_v.txt文件，可以看到文件开头内容如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">========================================================================</span><br><span class="line"></span><br><span class="line">** ELF Header Information</span><br><span class="line"></span><br><span class="line">    File Name: bsp_led.o // bsp_led.o文件</span><br><span class="line"></span><br><span class="line">    Machine class: ELFCLASS32 (32-bit)           // 32位机器</span><br><span class="line">    Data encoding: ELFDATA2LSB (Little endian)   // 小端格式 </span><br><span class="line">    Header version: EV_CURRENT (Current version)</span><br><span class="line">    Operating System ABI: none</span><br><span class="line">    ABI Version: 0</span><br><span class="line">    File Type: ET_REL (Relocatable object) (1)  // 可重定位类型</span><br><span class="line">    Machine: EM_ARM (ARM)</span><br><span class="line"></span><br><span class="line">    Entry offset (in SHF_ENTRYSECT section): 0x00000000</span><br><span class="line">    Flags: None (0x05000000)</span><br><span class="line"></span><br><span class="line">    ARM ELF revision: 5 (ABI version 2)</span><br><span class="line"></span><br><span class="line">    Header size: 52 bytes (0x34)</span><br><span class="line">    Program header entry size: 0 bytes (0x0)   // 程序头大小</span><br><span class="line">    Section header entry size: 40 bytes (0x28)</span><br><span class="line"></span><br><span class="line">    Program header entries: 0</span><br><span class="line">    Section header entries: 178</span><br><span class="line"></span><br><span class="line">    Program header offset: 0 (0x00000000)      // 程序头在文件中的位置(没有程序头)</span><br><span class="line">    Section header offset: 379672 (0x0005cb18) // 节区头在文件中的位置</span><br><span class="line"></span><br><span class="line">    Section header string table index: 175</span><br><span class="line"></span><br><span class="line">========================================================================</span><br></pre></td></tr></table></figure>

<p>在这个*.o文件中，它的ELF文件头中告诉我们它的程序头(Program header)大小为“0 bytes”，且程序头所在的文件位置偏移也为“0”，这说明它是没有程序头的。</p>
<h4 id="3-5-2-程序头"><a href="#3-5-2-程序头" class="headerlink" title="3.5.2 程序头"></a><font size=3>3.5.2 程序头</font></h4><p>接下来打开“ 流水灯_axf_elfInfo_v.txt”文件，查看工程的 流水灯.axf 文件的详细信息：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230415220024144.png" alt="image-20230415220024144" style="zoom: 33%;" />

<p>按照相同的方法，我们执行以下命令：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">PS D:\MyLinux\Ubuntu\Sharedfiles\3Linux\16-LV16\ebf_stm32f103_badao_std_code-master\46-MDK编译过程及文件全解\程序\MDK文</span><br><span class="line">件详解-GPIO输出—多彩流水灯\Output&gt; fromelf --text -v .\流水灯.axf --output ../elfInfo/流水灯_axf_elfInfo_v.txt</span><br></pre></td></tr></table></figure>

<p>这样就可以在上一级目录中生成“流水灯_axf_elfInfo_v.txt”文件，我们打开这个文件，文件头部内容如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">========================================================================</span><br><span class="line"></span><br><span class="line">** ELF Header Information</span><br><span class="line"></span><br><span class="line">    File Name: .\流水灯.axf</span><br><span class="line"></span><br><span class="line"># 中间部分省略......</span><br><span class="line"></span><br><span class="line">========================================================================</span><br><span class="line"></span><br><span class="line">** Program header #0</span><br><span class="line"></span><br><span class="line">    Type          : PT_LOAD (1)</span><br><span class="line">    File Offset   : 52 (0x34)</span><br><span class="line">    Virtual Addr  : 0x08000000</span><br><span class="line">    Physical Addr : 0x08000000</span><br><span class="line">    Size in file  : 1492 bytes (0x5d4)</span><br><span class="line">    Size in memory: 2516 bytes (0x9d4)</span><br><span class="line">    Flags         : PF_X + PF_W + PF_R + PF_ARM_ENTRY (0x80000007)</span><br><span class="line">    Alignment     : 8</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">========================================================================</span><br></pre></td></tr></table></figure>

<p>对比之下，可发现*.axf文件的ELF文件头对程序头的大小说明为非0值，且给出了它在文件的偏移地址，在输出信息之中，包含了程序头的详细信息。</p>
<p>程序头的“Physical Addr”描述了本程序要加载到的内存地址“0x0800 0000”，正好是STM32内部FLASH的首地址。“size in file”描述了本程序占据的空间大小为“1492 bytes”，它正是程序烧录到FLASH中需要占据的空间。这个大小等于在keil中编译时输出信息中的 Code + RO-data 的大小。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230415220615175.png" alt="image-20230415220615175" style="zoom:50%;" />

<h4 id="3-5-2-节区头"><a href="#3-5-2-节区头" class="headerlink" title="3.5.2 节区头"></a><font size=3>3.5.2 节区头</font></h4><p>在ELF的原文件中，紧接着程序头的一般是节区的主体信息，在节区主体信息之后是描述节区主体信息的节区头，我们来看看节区头中的信息了解概况。 通过对比*.o文件及*.axf文件的节区头部信息，可以清楚地看出这两种文件的区别：</p>
<ul>
<li>*.o文件的节区信息(“bsp_led_o_elfInfo_v.txt”文件)</li>
</ul>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">** Section #1</span><br><span class="line"></span><br><span class="line">    Name        : i.LED_GPIO_Config    // 节区名 </span><br><span class="line">    // 此节区包含程序定义的信息，其格式和含义都由程序来解释。</span><br><span class="line">    Type        : SHT_PROGBITS (0x00000001)</span><br><span class="line">    // 此节区在进程执行过程中占用内存。 节区包含可执行的机器指令。</span><br><span class="line">    Flags       : SHF_ALLOC + SHF_EXECINSTR (0x00000006)</span><br><span class="line">    Addr        : 0x00000000           // 地址</span><br><span class="line">    File Offset : 52 (0x34)            // 在文件中的偏移</span><br><span class="line">    Size        : 96 bytes (0x60)      // 大小</span><br><span class="line">    Link        : SHN_UNDEF</span><br><span class="line">    Info        : 0</span><br><span class="line">    Alignment   : 4                    // 字节对齐</span><br><span class="line">    Entry Size  : 0</span><br><span class="line">====================================</span><br></pre></td></tr></table></figure>

<p>这个节区的名称为LED_GPIO_Config，它正好是我们在bsp_led.c文件中定义的函数名。<strong>注意</strong>：编译时要勾选“【Options for Target 】&rarr; 【C&#x2F;C++】&rarr; 【One ELF Section per Function】”中的选项，生成的*.o文件内部的代码区域才会与C文件中定义的函数名一致，否则它会把多个函数合成一个代码段， 名字一般跟C文件中的函数名不同。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230415221049396.png" alt="image-20230415221049396" style="zoom: 33%;" />

<p>这个节区头描述的是该函数被编译后的节区信息，其中包含了节区的类型(指令类型SHT_PROGBITS)、节区应存储到的地址(0x00000000)、它主体信息在文件位置中的偏移(52)以及节区的大小(96 bytes)。</p>
<p>由于*.o文件是可重定位文件，所以它的地址并没有被分配，是0x00000000（假如文件中还有其它函数，该函数生成的节区中，对应的地址描述也都是0）。 当链接器链接时，根据这个节区头信息，在文件中找到它的主体内容，并根据它的类型，把它加入到主程序中，并分配实际地址，链接后生成的*.axf文件。</p>
<ul>
<li>*.axf文件的节区信息（“流水灯_axf_elfInfo_v.txt”）</li>
</ul>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">** Section #1</span><br><span class="line"></span><br><span class="line">    Name        : ER_IROM1                  // 节区名</span><br><span class="line">    // 此节区包含程序定义的信息，其格式和含义都由程序来解释。</span><br><span class="line">    Type        : SHT_PROGBITS (0x00000001)</span><br><span class="line">    // 此节区在进程执行过程中占用内存。 节区包含可执行的机器指令</span><br><span class="line">    Flags       : SHF_ALLOC + SHF_EXECINSTR (0x00000006)</span><br><span class="line">    Addr        : 0x08000000               // 地址</span><br><span class="line">    File Offset : 52 (0x34)           </span><br><span class="line">    Size        : 1492 bytes (0x5d4)       // 大小</span><br><span class="line">    Link        : SHN_UNDEF</span><br><span class="line">    Info        : 0</span><br><span class="line">    Alignment   : 4</span><br><span class="line">    Entry Size  : 0</span><br><span class="line">====================================</span><br><span class="line">** Section #2</span><br><span class="line"></span><br><span class="line">    Name        : RW_IRAM1                 // 节区名</span><br><span class="line">    // 包含将出现在程序的内存映像中的为初始化数据。 根据定义，当程序开始执行，系统</span><br><span class="line">    // 将把这些数据初始化为 0。</span><br><span class="line">    Type        : SHT_NOBITS (0x00000008)</span><br><span class="line">    // 此节区在进程执行过程中占用内存。 节区包含进程执行过程中将可写的数据。</span><br><span class="line">    Flags       : SHF_ALLOC + SHF_WRITE (0x00000003)</span><br><span class="line">    Addr        : 0x20000000              // 地址</span><br><span class="line">    File Offset : 1544 (0x608)</span><br><span class="line">    Size        : 1024 bytes (0x400)      // 大小</span><br><span class="line">    Link        : SHN_UNDEF</span><br><span class="line">    Info        : 0</span><br><span class="line">    Alignment   : 8</span><br><span class="line">    Entry Size  : 0</span><br><span class="line">====================================</span><br></pre></td></tr></table></figure>

<p>在*.axf文件中，主要包含了两个节区，一个名为ER_IROM1，一个名为RW_IRAM1，这些节区头信息中除了具有*.o文件中节区头描述的节区类型、文件位置偏移、大小之外，更重要的是它们都有具体的地址描述，其中 ER_IROM1的地址为0x08000000，而RW_IRAM1的地址为0x20000000，它们正好是STM32内部FLASH及SRAM的首地址，对应节区的大小就是程序需要占用FLASH及SRAM空间的实际大小。</p>
<p>也就是说，经过链接器后，它生成的*.axf文件已经汇总了其它*.o文件的所有内容，生成的ER_IROM1节区内容可直接写入到STM32内部FLASH的具体位置。例如，前面*.o文件中的i.LED_GPIO_Config节区已经被加入到*.axf文件的ER_IROM1节区的某地址。</p>
<h4 id="3-5-3-节区主体及反汇编代码"><a href="#3-5-3-节区主体及反汇编代码" class="headerlink" title="3.5.3 节区主体及反汇编代码"></a><font size=3>3.5.3 节区主体及反汇编代码</font></h4><p>使用fromelf的 -c 选项可以查看部分节区的主体信息，对于指令节区，可根据其内容查看相应的反汇编代码，我们打开“bsp_led_o_elfInfo_c.txt”文件可查看 这些信息：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">// *.o文件的LED_GPIO_Config节区及反汇编代码(bsp_led_o_elfInfo_c.txt文件)</span><br><span class="line">** Section #1 &#x27;i.LED_GPIO_Config&#x27; (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]</span><br><span class="line">    Size   : 96 bytes (alignment 4)</span><br><span class="line">    Address: 0x00000000</span><br><span class="line"></span><br><span class="line">    $t</span><br><span class="line">    i.LED_GPIO_Config</span><br><span class="line">    LED_GPIO_Config</span><br><span class="line">    	//  地址        内容  [ASCII码(无意义)]  内容对应的代码</span><br><span class="line">        0x00000000:    b508        ..      PUSH     &#123;r3,lr&#125;</span><br><span class="line">        0x00000002:    2101        .!      MOVS     r1,#1</span><br><span class="line">        0x00000004:    2008        .       MOVS     r0,#8</span><br><span class="line">        0x00000006:    f7fffffe    ....    BL       RCC_APB2PeriphClockCmd</span><br><span class="line">        0x0000000a:    2020                MOVS     r0,#0x20</span><br><span class="line">        0x0000000c:    f8ad0000    ....    STRH     r0,[sp,#0]</span><br><span class="line">        0x00000010:    2010        .       MOVS     r0,#0x10</span><br><span class="line">        0x00000012:    f88d0003    ....    STRB     r0,[sp,#3]</span><br><span class="line">        0x00000016:    2003        .       MOVS     r0,#3</span><br><span class="line">        0x00000018:    f88d0002    ....    STRB     r0,[sp,#2]</span><br><span class="line">        0x0000001c:    4669        iF      MOV      r1,sp</span><br><span class="line">        0x0000001e:    480f        .H      LDR      r0,[pc,#60] ; [0x5c] = 0x40010c00</span><br><span class="line">        0x00000020:    f7fffffe    ....    BL       GPIO_Init</span><br><span class="line">        0x00000024:    2001        .       MOVS     r0,#1</span><br><span class="line">// 下边的内容省略</span><br></pre></td></tr></table></figure>

<p>可看到，由于这是*.o文件，它的节区地址还是没有分配的，基地址为0x00000000，接着在LED_GPIO_Config标号之后，列出了一个表，表中包含了地址偏移、相应地址中的内容以及根据内容反汇编得到的指令。细看汇编指令，还可看到它包含了跳转到RCC_APB2PeriphClockCmd及GPIO_Init标号的语句，而且这两个跳转语句原来的内容都是“f7fffffe”，这是因为在*.o文件中并没有RCC_APB2PeriphClockCmd及GPIO_Init标号的具体地址索引，在*.axf文件中，这是不一样的。</p>
<p>接下来我们打开“流水灯_axf_elfInfo_c.txt”文件，查看*.axf文件中，ER_IROM1节区中对应LED_GPIO_Config的内容，我们执行以下命令生成这个文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">PS D:\MyLinux\Ubuntu\Sharedfiles\3Linux\16-LV16\ebf_stm32f103_badao_std_code-master\46-MDK编译过程及文件全解\程序\MDK文</span><br><span class="line">件详解-GPIO输出—多彩流水灯\Output&gt; fromelf --text -c .\流水灯.axf --output ../elfInfo/流水灯_axf_elfInfo_c.txt</span><br></pre></td></tr></table></figure>

<p>然后我们打开这个文件：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">// *.axf文件的LED_GPIO_Config反汇编代码(流水灯_axf_elfInfo_c.txt文件)</span><br><span class="line">	i.LED_GPIO_Config</span><br><span class="line">    LED_GPIO_Config</span><br><span class="line">        0x080002c4:    b508        ..      PUSH     &#123;r3,lr&#125;</span><br><span class="line">        0x080002c6:    2101        .!      MOVS     r1,#1</span><br><span class="line">        0x080002c8:    2008        .       MOVS     r0,#8</span><br><span class="line">        0x080002ca:    f000f82f    ../.    BL       RCC_APB2PeriphClockCmd ; 0x800032c</span><br><span class="line">        0x080002ce:    2020                MOVS     r0,#0x20</span><br><span class="line">        0x080002d0:    f8ad0000    ....    STRH     r0,[sp,#0]</span><br><span class="line">        0x080002d4:    2010        .       MOVS     r0,#0x10</span><br><span class="line">        0x080002d6:    f88d0003    ....    STRB     r0,[sp,#3]</span><br><span class="line">        0x080002da:    2003        .       MOVS     r0,#3</span><br><span class="line">        0x080002dc:    f88d0002    ....    STRB     r0,[sp,#2]</span><br><span class="line">        0x080002e0:    4669        iF      MOV      r1,sp</span><br><span class="line">        0x080002e2:    480f        .H      LDR      r0,[pc,#60] ; [0x8000320] = 0x40010c00</span><br><span class="line">        0x080002e4:    f7ffff5e    ..^.    BL       GPIO_Init ; 0x80001a4</span><br><span class="line">        0x080002e8:    2001        .       MOVS     r0,#1</span><br><span class="line">// 下边的内容省略</span><br></pre></td></tr></table></figure>

<p>可看到，除了基地址以及跳转地址不同之外，LED_GPIO_Config中的内容跟*.o文件中的一样。另外，由于*.o是独立的文件，而*.axf是整个工程汇总的文件，所以在*.axf中包含了所有调用到*.o文件节区的内容。例如，在“bsp_led_o_elfInfo_c.txt”(bsp_led.o文件的反汇编信息)中不包含RCC_APB2PeriphClockCmd及GPIO_Init的内容，而在“流水灯_axf_elfInfo_c.txt” (流水灯.axf文件的反汇编信息)中则可找到它们的具体信息，且它们也有具体的地址空间。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529204130641.png" alt="image-20230529204130641" style="zoom: 80%;" />

<p>在*.axf文件中，跳转到RCC_APB2PeriphClockCmd及GPIO_Init标号的这两个指令后都有注释，分别是“; 0x800032c”及“; 0x80001a4”，它们是这两个标号所在的具体地址，而且这两个跳转语句的跟*.o中的也有区别，内容分别为“f000f82f”及“f7ffff5e”（*.o中的均为f7fffffe）。这就是链接器链接的含义，它把不同*.o中的内容链接起来了。</p>
<h4 id="3-5-4-分散加载代码"><a href="#3-5-4-分散加载代码" class="headerlink" title="3.5.4 分散加载代码"></a><font size=3>3.5.4 分散加载代码</font></h4><p>前面提到程序有存储态及运行态，它们之间应有一个转化过程，<strong>把存储在内部FLASH中的RW-data数据拷贝至内部SRAM</strong>。然而我们的工程中并没有编写这样的代码，在汇编文件中也查不到该过程，芯片是如何知道FLASH的哪些数据应拷贝到SRAM的哪些区域呢？</p>
<p>通过查看“流水灯_axf_elfInfo_c.txt”的反汇编信息，可以看到到程序中具有一段名为“__scatterload”的分散加载代码，它是由 armlink 链接器自动生成的</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line">// 分散加载代码(流水灯_axf_elfInfo_c.txt文件)</span><br><span class="line">    .text</span><br><span class="line">    __scatterload</span><br><span class="line">    __scatterload_rt2</span><br><span class="line">        0x08000168:    4c06        .L      LDR      r4,[pc,#24] ; [0x8000184] = 0x80005c4</span><br><span class="line">        0x0800016a:    4d07        .M      LDR      r5,[pc,#28] ; [0x8000188] = 0x80005d4</span><br><span class="line">        0x0800016c:    e006        ..      B        0x800017c ; __scatterload + 20</span><br><span class="line">        0x0800016e:    68e0        .h      LDR      r0,[r4,#0xc]</span><br><span class="line">        0x08000170:    f0400301    @...    ORR      r3,r0,#1</span><br><span class="line">        0x08000174:    e8940007    ....    LDM      r4,&#123;r0-r2&#125;</span><br><span class="line">        0x08000178:    4798        .G      BLX      r3</span><br><span class="line">        0x0800017a:    3410        .4      ADDS     r4,r4,#0x10</span><br><span class="line">        0x0800017c:    42ac        .B      CMP      r4,r5</span><br><span class="line">        0x0800017e:    d3f6        ..      BCC      0x800016e ; __scatterload + 6</span><br><span class="line">        0x08000180:    f7ffffda    ....    BL       __main_after_scatterload ; 0x8000138</span><br><span class="line">    $d</span><br><span class="line">        0x08000184:    080005c4    ....    DCD    134219204</span><br><span class="line">        0x08000188:    080005d4    ....    DCD    134219220</span><br><span class="line">    $t</span><br><span class="line">// ... ...</span><br><span class="line">    i.__scatterload_copy</span><br><span class="line">    __scatterload_copy</span><br><span class="line">        0x080004a0:    e002        ..      B        0x80004a8 ; __scatterload_copy + 8</span><br><span class="line">        0x080004a2:    c808        ..      LDM      r0!,&#123;r3&#125;</span><br><span class="line">        0x080004a4:    1f12        ..      SUBS     r2,r2,#4</span><br><span class="line">        0x080004a6:    c108        ..      STM      r1!,&#123;r3&#125;</span><br><span class="line">        0x080004a8:    2a00        .*      CMP      r2,#0</span><br><span class="line">        0x080004aa:    d1fa        ..      BNE      0x80004a2 ; __scatterload_copy + 2</span><br><span class="line">        0x080004ac:    4770        pG      BX       lr</span><br><span class="line">    i.__scatterload_null</span><br><span class="line">    __scatterload_null</span><br><span class="line">        0x080004ae:    4770        pG      BX       lr</span><br><span class="line">    i.__scatterload_zeroinit</span><br><span class="line">    __scatterload_zeroinit</span><br><span class="line">        0x080004b0:    2000        .       MOVS     r0,#0</span><br><span class="line">        0x080004b2:    e001        ..      B        0x80004b8 ; __scatterload_zeroinit + 8</span><br><span class="line">        0x080004b4:    c101        ..      STM      r1!,&#123;r0&#125;</span><br><span class="line">        0x080004b6:    1f12        ..      SUBS     r2,r2,#4</span><br><span class="line">        0x080004b8:    2a00        .*      CMP      r2,#0</span><br><span class="line">        0x080004ba:    d1fb        ..      BNE      0x80004b4 ; __scatterload_zeroinit + 4</span><br><span class="line">        0x080004bc:    4770        pG      BX       lr</span><br><span class="line">        0x080004be:    0000        ..      MOVS     r0,r0</span><br></pre></td></tr></table></figure>

<p>这段分散加载代码包含了拷贝过程(主要使用LDM复制指令)，如：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0x08000174:    e8940007    ....    LDM      r4,&#123;r0-r2&#125;</span><br></pre></td></tr></table></figure>

<p>而LDM指令的操作数中包含了加载的源地址，这些地址中包含了内部FLASH存储的RW-data数据，执行这些指令后数据就会从FLASH地址加载到内部SRAM的地址。我们再来看一下这个文件的__main的反汇编代码部分：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">//__main的反汇编代码部分（流水灯_axf_elfInfo_c.txt文件）</span><br><span class="line">    .ARM.Collect$$$$00000000</span><br><span class="line">    .ARM.Collect$$$$00000001</span><br><span class="line">    __Vectors_End</span><br><span class="line">    __main</span><br><span class="line">    _main_stk</span><br><span class="line">        0x08000130:    f8dfd00c    ....    LDR      sp,__lit__00000000 ; [0x8000140] = 0x20000400</span><br><span class="line">    .ARM.Collect$$$$00000004</span><br><span class="line">    _main_scatterload</span><br><span class="line">        0x08000134:    f000f818    ....    BL       __scatterload ; 0x8000168</span><br></pre></td></tr></table></figure>

<p>可以看最后一行， “__scatterload ”的代码会被“__main”函数调用，__main在启动文件中的“Reset_Handler”会被调用，因而，在主体程序执行前，已经完成了分散加载过程。</p>
<h3 id="3-6-hex文件及bin文件"><a href="#3-6-hex文件及bin文件" class="headerlink" title="3.6 hex文件及bin文件"></a><font size=3>3.6 hex文件及bin文件</font></h3><p>若编译过程无误，即可把工程生成前面对应的*.axf文件，而在MDK中使用下载器(DAP&#x2F;JLINK&#x2F;ULINK等)下载程序或仿真的时候，MDK调用的就是*.axf文件，它解释该文件，然后控制下载器把*.axf中的代码内容下载到STM32芯片对应的存储空间，然后复位后芯片就开始执行代码了。</p>
<p>然而，脱离了MDK或IAR等工具，下载器就无法直接使用*.axf文件下载代码了，它们一般仅支持hex和bin格式的代码数据文件。默认情况下MDK都不会生成hex及bin文件，需要配置工程选项或使用fromelf命令。</p>
<h4 id="3-6-1-生成hex文件"><a href="#3-6-1-生成hex文件" class="headerlink" title="3.6.1 生成hex文件"></a><font size=3>3.6.1 生成hex文件</font></h4><p>生成hex文件的配置比较简单，在“【Options for Target】&rarr;【Output】&rarr;【Create Hex File】”中勾选该选项，然后编译工程即可。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230415223432834.png" alt="image-20230415223432834" style="zoom: 33%;" />

<h4 id="3-6-2-生成bin文件"><a href="#3-6-2-生成bin文件" class="headerlink" title="3.6.2 生成bin文件"></a><font size=3>3.6.2 生成bin文件</font></h4><p>使用MDK生成bin文件需要使用fromelf命令，在MDK的“【Options For Target】&rarr;【Users】”中加入：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fromelf --bin --output ..\..\Output\流水灯.bin ..\..\Output\流水灯.axf</span><br></pre></td></tr></table></figure>

<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230410231410382.png" alt="image-20230410231410382" style="zoom: 33%;" />

<p>该指令是根据本机及工程的配置而写的，在不同的系统环境或不同的工程中，指令内容都不一样，我们需要理解它， 才能为自己的工程定制指令，首先看看fromelf的帮助（前提是已经将 fromelf 加入环境变量）：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">PS C:\Users\20380&gt; fromelf</span><br><span class="line">Product: MDK Plus 5.29</span><br><span class="line">Component: ARM Compiler 5.06 update 6 (build 750)</span><br><span class="line">Tool: fromelf [4d35e3]</span><br><span class="line">For support see http://www.arm.com/support</span><br><span class="line">Software supplied by: ARM Limited</span><br><span class="line"></span><br><span class="line">ARM image conversion utility</span><br><span class="line">fromelf [options] input_file</span><br><span class="line"></span><br><span class="line">Options:</span><br><span class="line">       --help         display this help screen</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">中间部分省略.....</span></span><br><span class="line">Binary Output Formats:</span><br><span class="line">       --bin          Plain Binary</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">中间部分省略.....</span></span><br><span class="line">Output Formats Requiring Debug Information</span><br><span class="line">       --fieldoffsets Assembly Language Description of Structures/Classes</span><br><span class="line">       --expandarrays Arrays inside and outside structures are expanded</span><br><span class="line"></span><br><span class="line">Other Output Formats:</span><br><span class="line">       --elf         ELF</span><br><span class="line">       --text        Text Information</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">中间部分省略.....</span></span><br></pre></td></tr></table></figure>

<p>我们在MDK输入的指令格式是遵守fromelf帮助里的指令格式说明的，其格式为：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fromelf [options] input_file</span><br></pre></td></tr></table></figure>

<p>其中optinos是指令选项，一个指令支持输入多个选项，每个选项之间使用空格隔开，我们的实例中使用“–bin”选项设置输出bin文件，使用“–output file”选项设置输出文件的名字为“..\..\Output流水灯.bin”，这个名字是一个相对路径格式，一个“..”表示当前目录的上一层，两个“..”表示上两层 目录（当前目录是指uvprojx工程文件所在的位置）。如果不了解如何使用“..”表示路径，可使用MDK命令输入框后面的文件夹图标打开文件浏览器选择 文件，加入绝对路径，在命令的最后使用“..\..\Output流水灯.axf”作为命令的输入文件。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image371.jpeg" alt="图 40‑38 fromelf命令格式分解" style="zoom:40%;" />

<p>fromelf需要根据工程的*.axf文件输入来转换得到bin文件，所以在命令的输入文件参数中要选择本工程对应的*.axf文件，于是在MDK命令输入栏中，我们把fromelf指令放置在“After Build&#x2F;Rebuild”(工程构建完成后执行)一栏，这样设置后，工程构建完成生成了最新的*.axf文件，MDK再执行fromelf指令，从而得到最新的bin文件。</p>
<p>设置完成生成hex的选项或添加了生成bin的用户指令后，点击工程的编译(build)按钮，重新编译工程。就会有bin文件生成啦：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529205311123.png" alt="image-20230529205311123" style="zoom:50%;" />

<h4 id="3-6-3-hex文件格式"><a href="#3-6-3-hex文件格式" class="headerlink" title="3.6.3 hex文件格式"></a><font size=3>3.6.3 hex文件格式</font></h4><p>hex是Intel公司制定的一种使用ASCII文本记录机器码或常量数据的文件格式，这种文件常常用来记录将要存储到ROM中的数据，绝大多数下载器支持该格式。一个hex文件由多条记录组成，而每条记录由五个部分组成，格式形如“:llaaaatt[dd…]cc”记录的各个部分介绍如下：</p>
<ul>
<li>“:” ：每条记录的开头都使用冒号来表示一条记录的开始；</li>
<li>ll ：以16进制数表示这条记录的主体数据区的长度(即后面[dd…]的长度)；</li>
<li>aaaa:表示这条记录中的内容应存放到FLASH中的起始地址；</li>
<li>tt：表示这条记录的类型，它包含中的各种类型；</li>
</ul>
<details class="folding-tag" 点击查看tt的取值><summary> 添加说明 </summary>
              <div class='content'>
              <table><thead><tr><th>tt的值</th><th>代表的类型</th></tr></thead><tbody><tr><td>00</td><td>数据记录</td></tr><tr><td>01</td><td>本文件结束记录</td></tr><tr><td>02</td><td>扩展地址记录</td></tr><tr><td>04</td><td>扩展线性地址记录(表示后面的记录按个这地址递增)</td></tr><tr><td>05</td><td>表示一个线性地址记录的起始(只适用于ARM)</td></tr></tbody></table>
              </div>
            </details>

<ul>
<li>dd ：表示一个字节的数据，一条记录中可以有多个字节数据，ll区表示了它有多少个字节的数据；</li>
<li>cc ：表示本条记录的校验和，它是前面所有16进制数据 (除冒号外，两个为一组)的和对256取模运算的结果的补码。</li>
</ul>
<p>例如，“流水灯”工程生成的hex文件前几条记录如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">// Hex文件实例(流水灯.hex文件，可直接用记事本打开)</span><br><span class="line">:020000040800F2</span><br><span class="line">:10000000000400204501000829030008BF02000881</span><br><span class="line">:10001000250300088D0100089D0400080000000071</span><br><span class="line">:100020000000000000000000000000004D03000878</span><br><span class="line">:1000300091010008000000002B03000839040008AB</span><br><span class="line">:100040005F0100085F0100085F0100085F01000810</span><br></pre></td></tr></table></figure>

<ul>
<li>第一条记录解释如下：</li>
</ul>
<p>（1）02：表示这条记录数据区的长度为2字节；</p>
<p>（2）0000：表示这条记录要存储到的地址；</p>
<p>（3）04：表示这是一条扩展线性地址记录；</p>
<p>（4）0800：由于这是一条扩展线性地址记录，所以这部分表示地址的高16位，与前面的“0000”结合在一起，表示要扩展的线性地址为“0x0800 0000”，这正好是STM32内部FLASH的首地址；</p>
<p>（5）F2：表示校验和，它的值为(0x02+0x00+0x00+0x04+0x08+0x00)%256的值再取补码。</p>
<ul>
<li>再来看第二条记录：</li>
</ul>
<p>（1）10：表示这条记录数据区的长度为2字节；</p>
<p>（2）0000：表示这条记录所在的地址，与前面的扩展记录结合，表示这条记录要存储的FLASH首地址为(0x0800 0000+0x0000)；</p>
<p>（3）00：表示这是一条数据记录，数据区的是地址；</p>
<p>（4）000400204501000829030008BF020008：这是要按地址存储的数据；</p>
<p>（5）81:校验和</p>
<p>为了更清楚地对比bin、hex及axf文件的差异，我们来查看这些文件内部记录的信息来进行对比。</p>
<h4 id="3-6-4-hex、bin及axf文件的区别与联系"><a href="#3-6-4-hex、bin及axf文件的区别与联系" class="headerlink" title="3.6.4 hex、bin及axf文件的区别与联系"></a><font size=3>3.6.4 hex、bin及axf文件的区别与联系</font></h4><p>bin、hex及axf文件都包含了指令代码，但它们的信息丰富程度是不一样的。</p>
<ul>
<li>bin文件是最直接的代码映像，它记录的内容就是要存储到FLASH的二进制数据(机器码本质上就是二进制数据)， 在FLASH中是什么形式它就是什么形式，没有任何辅助信息，包括大小端格式也没有，因此下载器需要有针对芯片FLASH平台的辅助文件才能正常下载(一般下载器程序会有匹配的这些信息)；</li>
<li>hex文件是一种使用十六进制符号表示的代码记录，记录了代码应该存储到FLASH的哪个地址，下载器可以根据这些信息辅助下载；</li>
<li>axf文件，不仅包含代码数据，还包含了工程的各种信息，因此它也是三个文件中最大的。</li>
</ul>
<p>同一个工程生成的bin、hex及axf文件的大小如下图：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416140839500.png" alt="image-20230416140839500" style="zoom:33%;" />

<p>实际上，这个工程要烧写到FLASH的内容总大小为1492字节，然而在Windows中查看的bin文件却比它大( bin文件是FLASH的代码映像，大小应一致)，这是因为Windows文件显示单位的原因，使用右键查看文件的属性，可以查看它实际记录内容的大小</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416140927118.png" alt="image-20230416140927118" style="zoom:33%;" />

<p>接下来我们打开本工程的“流水灯.bin”、“流水灯.hex”及由“流水灯.axf”使用fromelf工具输出的反汇编文件“流水灯_axf_elfInfo_c.txt” 文件：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image412.jpeg" alt="image412" style="zoom:50%;" />

<p>在“流水灯_axf_elfInfo_c.txt”文件中不仅可以看到代码数据，还有具体的标号、地址以及反汇编得到的代码，虽然它不是*.axf文件的原始内容，但因为它是通过*.axf文件fromelf工具生成的，我们可认为*.axf文件本身记录了大量这些信息，它的内容非常丰富，熟悉汇编语言的人可轻松阅读。</p>
<p>在hex文件中包含了地址信息以及地址中的内容，而在bin文件中仅包含了内容，连存储的地址信息都没有。观察可知，bin、hex及axf文件中的数据内容都是相同的，它们存储的都是机器码。这就是它们三都之间的区别与联系。</p>
<p>由于文件中存储的都是机器码，该图是根据axf文件的GPIO_Init函数的机器码，在bin及hex中找到的对应位置。 所以经验丰富的人是有可能从bin或hex文件中恢复出汇编代码的，只是成本较高，但不是不可能。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image421.jpeg" alt="GPIO_Init函数的代码数据在三个文件中的表示" style="zoom:50%;" />

<p>如果芯片没有做任何加密措施，使用下载器可以直接从芯片读回它存储在FLASH中的数据，从而得到bin映像文件，根据芯片型号还原出部分代码即可进行修改，甚至不用修改代码，直接根据目标产品的硬件PCB，抄出一样的板子，再把bin映像下载芯片，直接山寨出目标产品，所以在实际的生产中，一定要注意做好加密措施。由于axf文件中含有大量的信息，且直接使用fromelf即可反汇编代码，所以更不要随便泄露axf文件。lib文件也能反使用fromelf文件反汇编代码，不过它不能还原出C代码，由于lib文件的主要目的是为了保护C源代码，也算是达到了它的要求。</p>
<h3 id="3-7-总结"><a href="#3-7-总结" class="headerlink" title="3.7 总结"></a><font size=3>3.7 总结</font></h3><p>总结一下bin、hex、axf、elf文件格式有什么区别吧：从存储数据的信息量上看：elf &gt; axf &gt; hex &gt; bin，所以这也就确定了只能将大信息量的文件格式向小信息量的文件格式转换，如只能将 hex 文件转换为 bin 文件，当然如果指定了下载地址，也可以将 bin 转换为 hex 文件。</p>
<table>
<thead>
<tr>
<th>文件类型</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>BIN文件</td>
<td>bin文件是纯粹的机器码，没有地址信息，不能使用记事本直接打开，要使用bin文件阅读器才能打开，如果使用bin文件烧录程序时，<strong>需要指定下载地址</strong>。一些下载器只能使用BIN文件进行下载，在进行OTA远程升级时必须使用bin文件。</td>
</tr>
<tr>
<td>HEX文件</td>
<td>一般是指Intel标准的hex文件，可以使用记事本直接打开，是十六进制数据，包含了基地址、偏移量、校验和、文件开始和结束标志等信息，与bin文件最大的不同就是<strong>包含了下载地址</strong>。由于hex文件是十六进制数据，而bin文件是二进制数据，如十六进制0xFF，用二进制表示为1111 1111，所以hex文件要比bin文件大得多。与axf文件相比，不含调试信息，不能用于调试。</td>
</tr>
<tr>
<td>AXF文件</td>
<td><strong>包含了调试信息</strong>，如进行在Keil环境使用Debug功能时，就是先将axf文件下载到芯片内，才能进行调试。如使用J-Link的J-Scope功能时，必须使用axf文件。</td>
</tr>
<tr>
<td>ELF文件</td>
<td>是由GCC编译器生成的。elf文件可以直接转换为hex和bin。</td>
</tr>
</tbody></table>
<h2 id="4-Listing目录下文件"><a href="#4-Listing目录下文件" class="headerlink" title="4. Listing目录下文件"></a><font size=3>4. Listing目录下文件</font></h2><p>在Listing目录下包含了*.map及*.lst文件，它们都是文本格式的，可使用Windows的记事本软件打开。其中lst文件仅包含了一些汇编符号的链接信息，这些文件中<strong>重点是map文件</strong>。</p>
<h3 id="4-1-Listing目录位置选择"><a href="#4-1-Listing目录位置选择" class="headerlink" title="4.1 Listing目录位置选择"></a><font size=3>4.1 Listing目录位置选择</font></h3><p>这里存放的都是链接器链接过程中用到的或者生成的文件，我们也是可以自行配置目录位置的：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529200721976.png" alt="image-20230529200721976" style="zoom: 33%;" />

<p>【Options for Targe】&rarr;【Listing】&rarr;【SelectFolder for Listings】”选项配置这些文件的输出路径 。</p>
<h3 id="4-2-打开map文件"><a href="#4-2-打开map文件" class="headerlink" title="4.2 打开map文件"></a><font size=3>4.2 打开map文件</font></h3><p>map文件存在于Listing目录中，我们怎么在MDK中打开？我们直接双击这里：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529205801781.png" alt="image-20230529205801781" style="zoom: 33%;" />

<p>双击之后没打开？这个我也不清楚，但是重新配置一下listing目录的位置就可以双击打开啦，我也不是很明白为什么，可能是需要map文件在某个子目录吧。</p>
<h3 id="4-3-map文件说明"><a href="#4-3-map文件说明" class="headerlink" title="4.3 map文件说明"></a><font size=3>4.3 map文件说明</font></h3><p>map文件是由链接器生成的，它主要包含交叉链接信息，查看该文件可以了解工程中各种符号之间的引用以及整个工程的Code、RO-data、RW-data以及ZI-data的详细及汇总信息。它的内容中主要包含了“节区的跨文件引用”、“删除无用节区”、“符号映像表”、“存储器映像索引”以及“映像组件大小”，接下来是各部分介绍。</p>
<h4 id="4-3-1-节区的跨文件引用"><a href="#4-3-1-节区的跨文件引用" class="headerlink" title="4.3.1 节区的跨文件引用"></a><font size=3>4.3.1 节区的跨文件引用</font></h4><p>打开“流水灯.map”文件，可看到它的第一部分——节区的跨文件引用(<strong>Section Cross References</strong>)：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">// 节区的跨文件引用部分(流水灯.map文件)</span><br><span class="line">Component: ARM Compiler 5.06 update 6 (build 750) Tool: armlink [4d35ed]</span><br><span class="line"></span><br><span class="line">==============================================================================</span><br><span class="line"></span><br><span class="line">Section Cross References</span><br><span class="line"></span><br><span class="line">    startup_stm32f10x_hd.o(RESET) refers to startup_stm32f10x_hd.o(STACK) for __initial_sp</span><br><span class="line">    startup_stm32f10x_hd.o(RESET) refers to startup_stm32f10x_hd.o(.text) for Reset_Handler</span><br><span class="line">    // 中间省略......</span><br><span class="line">    startup_stm32f10x_hd.o(RESET) refers to stm32f10x_it.o(i.SysTick_Handler) for SysTick_Handler</span><br><span class="line">    // 中间省略......</span><br><span class="line">    main.o(i.main) refers to bsp_led.o(i.LED_GPIO_Config) for LED_GPIO_Config</span><br><span class="line">    main.o(i.main) refers to main.o(i.Delay) for Delay</span><br><span class="line">    bsp_led.o(i.LED_GPIO_Config) refers to stm32f10x_rcc.o(i.RCC_APB2PeriphClockCmd) for RCC_APB2PeriphClockCmd</span><br><span class="line">    bsp_led.o(i.LED_GPIO_Config) refers to stm32f10x_gpio.o(i.GPIO_Init) for GPIO_Init</span><br><span class="line">    bsp_led.o(i.LED_GPIO_Config) refers to stm32f10x_gpio.o(i.GPIO_SetBits) for GPIO_SetBits</span><br><span class="line">    // 后边省略......</span><br></pre></td></tr></table></figure>

<p>在这部分中，详细列出了各个*.o文件之间的符号引用。由于*.o文件是由asm或c&#x2F;c++源文件编译后生成的，各个文件及文件内的节区间互相独立，链接器根据它们之间的互相引用链接起来，链接的详细信息在这个“Section Cross References”一一列出。</p>
<p>例如，开头部分说明的是startup_stm32f10x.o文件中的“RESET”节区分为它使用的“__initial_sp” 符号引用了同文件“STACK”节区。</p>
<p>我们继续浏览，可看到main.o文件的引用说明，如说明main.o文件的i.main节区为它使用的 LED_GPIO_Config 符号引用了 bsp_led.o 文件 i.LED_GPIO_Config 节区。</p>
<p>同样地，下面还有bsp_led.o文件的引用说明，如说明了bsp_led.o文件的i.LED_GPIO_Config节区为它使用的GPIO_Init符号引用了stm32f10x_gpio.o文件的i.GPIO_Init节区。</p>
<p>可以了解到，这些跨文件引用的符号其实就是源文件中的函数名、变量名。有时在构建工程的时候，编译器会输出 “Undefined symbol xxx (referred from xxx.o)” 这样的提示，该提示的原因就是在链接过程中，某个文件无法在外部找到它引用的标号，因而产生链接错误。例如，我们把bsp_led.c文件中定义的函数LED_GPIO_Config改名为LED_GPIO_ConfigA，而不修改main.c文件中的调用，就会出现main文件无法找到LED_GPIO_Config符号的提示（Undefined symbol xxxx from xxx.o）。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416143210100.png" alt="image-20230416143210100" style="zoom: 33%;" />

<h4 id="4-3-2-删除无用节区"><a href="#4-3-2-删除无用节区" class="headerlink" title="4.3.2 删除无用节区"></a><font size=3>4.3.2 删除无用节区</font></h4><p>map文件的第二部分是删除无用节区的说明(<strong>Removing Unused input sections from the image</strong>)：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">//删除无用节区部分(流水灯.map文件)</span><br><span class="line">Removing Unused input sections from the image.</span><br><span class="line"></span><br><span class="line">    Removing startup_stm32f10x_hd.o(HEAP), (512 bytes).</span><br><span class="line">    Removing core_cm3.o(.emb_text), (32 bytes).</span><br><span class="line">    Removing system_stm32f10x.o(i.SystemCoreClockUpdate), (164 bytes).</span><br><span class="line">    Removing system_stm32f10x.o(.data), (20 bytes).</span><br><span class="line">    Removing misc.o(i.NVIC_Init), (112 bytes).</span><br><span class="line">    Removing misc.o(i.NVIC_PriorityGroupConfig), (20 bytes).</span><br><span class="line">    Removing misc.o(i.NVIC_SetVectorTable), (20 bytes).</span><br><span class="line">    // 后边的省略</span><br></pre></td></tr></table></figure>

<p>这部分列出了在链接过程它发现工程中未被引用的节区，这些未被引用的节区将会被删除(指不加入到*.axf文件，不是指在*.o文件删除)，这样可以防止这些无用数据占用程序空间。</p>
<p>例如，上面的信息中说明startup_stm32f10x.o中的HEAP(在启动文件中定义的用于动态分配的“堆”区)以及 stm32f10x_adc.o的各个节区都被删除了，因为在我们这个工程中没有使用动态内存分配，也没有引用任何stm32f10x_adc.c中的内容。由此也可以知道，虽然我们把STM32HAL库的各个外设对应的c库文件都添加到了工程，但不必担心这会使工程变得臃肿，因为未被引用的节区内容不会被加入到最终的机器码文件中。</p>
<h4 id="4-3-3-符号映像表"><a href="#4-3-3-符号映像表" class="headerlink" title="4.3.3 符号映像表"></a><font size=3>4.3.3 符号映像表</font></h4><p>map文件的第三部分是符号映像表(<strong>Image Symbol Table</strong>)：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line">//符号映像表部分(流水灯.map文件)</span><br><span class="line">Image Symbol Table</span><br><span class="line"></span><br><span class="line">    Local Symbols</span><br><span class="line"></span><br><span class="line">    Symbol Name                              Value     Ov Type        Size  Object(Section)</span><br><span class="line">	// 中间部分省略......</span><br><span class="line">    i.DebugMon_Handler                       0x08000190   Section        0  stm32f10x_it.o(i.DebugMon_Handler)</span><br><span class="line">    i.Delay                                  0x08000192   Section        0  main.o(i.Delay)</span><br><span class="line">    i.GPIO_Init                              0x080001a4   Section        0  stm32f10x_gpio.o(i.GPIO_Init)</span><br><span class="line">    i.GPIO_SetBits                           0x080002ba   Section        0  stm32f10x_gpio.o(i.GPIO_SetBits)</span><br><span class="line">    i.HardFault_Handler                      0x080002be   Section        0  stm32f10x_it.o(i.HardFault_Handler)</span><br><span class="line">    i.LED_GPIO_Config                        0x080002c4   Section        0  bsp_led.o(i.LED_GPIO_Config)</span><br><span class="line">    i.MemManage_Handler                      0x08000324   Section        0  stm32f10x_it.o(i.MemManage_Handler)</span><br><span class="line">    i.NMI_Handler                            0x08000328   Section        0  stm32f10x_it.o(i.NMI_Handler)</span><br><span class="line">    i.PendSV_Handler                         0x0800032a   Section        0  stm32f10x_it.o(i.PendSV_Handler)</span><br><span class="line">    i.RCC_APB2PeriphClockCmd                 0x0800032c   Section        0  stm32f10x_rcc.o(i.RCC_APB2PeriphClockCmd)</span><br><span class="line">    i.SVC_Handler                            0x0800034c   Section        0  stm32f10x_it.o(i.SVC_Handler)</span><br><span class="line">    i.SetSysClock                            0x0800034e   Section        0  system_stm32f10x.o(i.SetSysClock)</span><br><span class="line">    SetSysClock                              0x0800034f   Thumb Code     8  system_stm32f10x.o(i.SetSysClock)</span><br><span class="line">    i.SetSysClockTo72                        0x08000358   Section        0  system_stm32f10x.o(i.SetSysClockTo72)</span><br><span class="line">    SetSysClockTo72                          0x08000359   Thumb Code   214  system_stm32f10x.o(i.SetSysClockTo72)</span><br><span class="line">    i.SysTick_Handler                        0x08000438   Section        0  stm32f10x_it.o(i.SysTick_Handler)</span><br><span class="line">    i.SystemInit                             0x0800043c   Section        0  system_stm32f10x.o(i.SystemInit)</span><br><span class="line">    i.UsageFault_Handler                     0x0800049c   Section        0  stm32f10x_it.o(i.UsageFault_Handler)</span><br><span class="line">    i.__scatterload_copy                     0x080004a0   Section       14  handlers.o(i.__scatterload_copy)</span><br><span class="line">    i.__scatterload_null                     0x080004ae   Section        2  handlers.o(i.__scatterload_null)</span><br><span class="line">    i.__scatterload_zeroinit                 0x080004b0   Section       14  handlers.o(i.__scatterload_zeroinit)</span><br><span class="line">    i.main                                   0x080004c0   Section        0  main.o(i.main)</span><br><span class="line">    STACK                                    0x20000000   Section     1024  startup_stm32f10x_hd.o(STACK)</span><br><span class="line"></span><br><span class="line">    Global Symbols</span><br><span class="line"></span><br><span class="line">    Symbol Name                              Value     Ov Type        Size  Object(Section)</span><br><span class="line">    // 中间部分省略</span><br><span class="line">    LED_GPIO_Config                          0x080002c5   Thumb Code    90  bsp_led.o(i.LED_GPIO_Config)</span><br><span class="line">    MemManage_Handler                        0x08000325   Thumb Code     4  stm32f10x_it.o(i.MemManage_Handler)</span><br><span class="line">    NMI_Handler                              0x08000329   Thumb Code     2  stm32f10x_it.o(i.NMI_Handler)</span><br><span class="line">    PendSV_Handler                           0x0800032b   Thumb Code     2  stm32f10x_it.o(i.PendSV_Handler)</span><br><span class="line">    RCC_APB2PeriphClockCmd                   0x0800032d   Thumb Code    26  stm32f10x_rcc.o(i.RCC_APB2PeriphClockCmd)</span><br><span class="line">    SVC_Handler                              0x0800034d   Thumb Code     2  stm32f10x_it.o(i.SVC_Handler)</span><br><span class="line">    SysTick_Handler                          0x08000439   Thumb Code     2  stm32f10x_it.o(i.SysTick_Handler)</span><br><span class="line">    SystemInit                               0x0800043d   Thumb Code    78  system_stm32f10x.o(i.SystemInit)</span><br><span class="line">    UsageFault_Handler                       0x0800049d   Thumb Code     4  stm32f10x_it.o(i.UsageFault_Handler)</span><br><span class="line">    __scatterload_copy                       0x080004a1   Thumb Code    14  handlers.o(i.__scatterload_copy)</span><br><span class="line">    __scatterload_null                       0x080004af   Thumb Code     2  handlers.o(i.__scatterload_null)</span><br><span class="line">    __scatterload_zeroinit                   0x080004b1   Thumb Code    14  handlers.o(i.__scatterload_zeroinit)</span><br><span class="line">    main                                     0x080004c1   Thumb Code   252  main.o(i.main)</span><br><span class="line">    Region$$Table$$Base                      0x080005c4   Number         0  anon$$obj.o(Region$$Table)</span><br><span class="line">    Region$$Table$$Limit                     0x080005d4   Number         0  anon$$obj.o(Region$$Table)</span><br><span class="line">    __initial_sp                             0x20000400   Data           0  startup_stm32f10x_hd.o(STACK)</span><br><span class="line">	// 后边的省略</span><br></pre></td></tr></table></figure>

<p>这个表列出了被引用的各个符号在存储器中的具体地址、占据的空间大小等信息。如我们可以查到LED_GPIO_Config符号存储在0x080002c4地址，它属于Thumb Code类型，大小为90字节，它所在的节区为bsp_led.o文件的i.LED_GPIO_Config节区。</p>
<h4 id="4-3-4-存储器映像索引"><a href="#4-3-4-存储器映像索引" class="headerlink" title="4.3.4 存储器映像索引"></a><font size=3>4.3.4 存储器映像索引</font></h4><p>map文件的第四部分是存储器映像索引(<strong>Memory Map of the image</strong>)：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line">// 存储器映像索引部分(流水灯.map文件)</span><br><span class="line">Memory Map of the image</span><br><span class="line"></span><br><span class="line">  Image Entry point : 0x08000131</span><br><span class="line"></span><br><span class="line">  Load Region LR_IROM1 (Base: 0x08000000, Size: 0x000005d4, Max: 0x00080000, ABSOLUTE)</span><br><span class="line"></span><br><span class="line">    Execution Region ER_IROM1 (Exec base: 0x08000000, Load base: 0x08000000, Size: 0x000005d4, Max: 0x00080000, ABSOLUTE)</span><br><span class="line"></span><br><span class="line">    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object</span><br><span class="line"></span><br><span class="line">    0x08000000   0x08000000   0x00000130   Data   RO            3    RESET               startup_stm32f10x_hd.o</span><br><span class="line">    0x08000130   0x08000130   0x00000000   Code   RO         3207  * .ARM.Collect$$$$00000000  mc_w.l(entry.o)</span><br><span class="line">    0x08000130   0x08000130   0x00000004   Code   RO         3210    .ARM.Collect$$$$00000001  mc_w.l(entry2.o)</span><br><span class="line">    0x08000134   0x08000134   0x00000004   Code   RO         3213    .ARM.Collect$$$$00000004  mc_w.l(entry5.o)</span><br><span class="line">    0x08000138   0x08000138   0x00000000   Code   RO         3215    .ARM.Collect$$$$00000008  mc_w.l(entry7b.o)</span><br><span class="line">    0x08000138   0x08000138   0x00000000   Code   RO         3217    .ARM.Collect$$$$0000000A  mc_w.l(entry8b.o)</span><br><span class="line">    0x08000138   0x08000138   0x00000008   Code   RO         3218    .ARM.Collect$$$$0000000B  mc_w.l(entry9a.o)</span><br><span class="line">    0x08000140   0x08000140   0x00000000   Code   RO         3220    .ARM.Collect$$$$0000000D  mc_w.l(entry10a.o)</span><br><span class="line">    0x08000140   0x08000140   0x00000000   Code   RO         3222    .ARM.Collect$$$$0000000F  mc_w.l(entry11a.o)</span><br><span class="line">    0x08000140   0x08000140   0x00000004   Code   RO         3211    .ARM.Collect$$$$00002712  mc_w.l(entry2.o)</span><br><span class="line">    0x08000144   0x08000144   0x00000024   Code   RO            4    .text               startup_stm32f10x_hd.o</span><br><span class="line">    0x08000168   0x08000168   0x00000024   Code   RO         3224    .text               mc_w.l(init.o)</span><br><span class="line">    0x0800018c   0x0800018c   0x00000004   Code   RO         3129    i.BusFault_Handler  stm32f10x_it.o</span><br><span class="line">    0x08000190   0x08000190   0x00000002   Code   RO         3130    i.DebugMon_Handler  stm32f10x_it.o</span><br><span class="line">    0x08000192   0x08000192   0x00000012   Code   RO         3108    i.Delay             main.o</span><br><span class="line">    0x080001a4   0x080001a4   0x00000116   Code   RO         1292    i.GPIO_Init         stm32f10x_gpio.o</span><br><span class="line">    0x080002ba   0x080002ba   0x00000004   Code   RO         1300    i.GPIO_SetBits      stm32f10x_gpio.o</span><br><span class="line">    0x080002be   0x080002be   0x00000004   Code   RO         3131    i.HardFault_Handler  stm32f10x_it.o</span><br><span class="line">    0x080002c2   0x080002c2   0x00000002   PAD</span><br><span class="line">    0x080002c4   0x080002c4   0x00000060   Code   RO         3192    i.LED_GPIO_Config   bsp_led.o</span><br><span class="line">    0x08000324   0x08000324   0x00000004   Code   RO         3132    i.MemManage_Handler  stm32f10x_it.o</span><br><span class="line">    0x08000328   0x08000328   0x00000002   Code   RO         3133    i.NMI_Handler       stm32f10x_it.o</span><br><span class="line">    0x0800032a   0x0800032a   0x00000002   Code   RO         3134    i.PendSV_Handler    stm32f10x_it.o</span><br><span class="line">    0x0800032c   0x0800032c   0x00000020   Code   RO         1710    i.RCC_APB2PeriphClockCmd  stm32f10x_rcc.o</span><br><span class="line">    0x0800034c   0x0800034c   0x00000002   Code   RO         3135    i.SVC_Handler       stm32f10x_it.o</span><br><span class="line">    0x0800034e   0x0800034e   0x00000008   Code   RO           24    i.SetSysClock       system_stm32f10x.o</span><br><span class="line">    0x08000356   0x08000356   0x00000002   PAD</span><br><span class="line">    0x08000358   0x08000358   0x000000e0   Code   RO           25    i.SetSysClockTo72   system_stm32f10x.o</span><br><span class="line">    0x08000438   0x08000438   0x00000002   Code   RO         3136    i.SysTick_Handler   stm32f10x_it.o</span><br><span class="line">    0x0800043a   0x0800043a   0x00000002   PAD</span><br><span class="line">    0x0800043c   0x0800043c   0x00000060   Code   RO           27    i.SystemInit        system_stm32f10x.o</span><br><span class="line">    0x0800049c   0x0800049c   0x00000004   Code   RO         3137    i.UsageFault_Handler  stm32f10x_it.o</span><br><span class="line">    0x080004a0   0x080004a0   0x0000000e   Code   RO         3228    i.__scatterload_copy  mc_w.l(handlers.o)</span><br><span class="line">    0x080004ae   0x080004ae   0x00000002   Code   RO         3229    i.__scatterload_null  mc_w.l(handlers.o)</span><br><span class="line">    0x080004b0   0x080004b0   0x0000000e   Code   RO         3230    i.__scatterload_zeroinit  mc_w.l(handlers.o)</span><br><span class="line">    0x080004be   0x080004be   0x00000002   PAD</span><br><span class="line">    0x080004c0   0x080004c0   0x00000104   Code   RO         3109    i.main              main.o</span><br><span class="line">    0x080005c4   0x080005c4   0x00000010   Data   RO         3226    Region$$Table       anon$$obj.o</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    Execution Region RW_IRAM1 (Exec base: 0x20000000, Load base: 0x080005d4, Size: 0x00000400, Max: 0x00010000, ABSOLUTE)</span><br><span class="line"></span><br><span class="line">    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object</span><br><span class="line"></span><br><span class="line">    0x20000000        -       0x00000400   Zero   RW            1    STACK               startup_stm32f10x_hd.o</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">==============================================================================</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>工程的存储器映像索引分为 ER_IROM1 及 RW_IRAM1 部分，它们分别对应STM32内部FLASH及SRAM的空间。相对于符号映像表，这个索引表描述的单位是节区，而且它描述的主要信息中包含了节区的类型及属性，由此可以区分Code、RO-data、RW-data及ZI-data。</p>
<ul>
<li>（1）加载域和执行域</li>
</ul>
<p>我们先来看一下这两个部分：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529211803575.png" alt="image-20230529211803575" style="zoom:50%;" />

<p>框中圈出来的，翻译过来就是加载区域和执行区域，加载区域基地址是0x08000000，最大大小为0x0008000，换算一下就是512KB，这就是我们整个内部FLASH，执行区域的基地址为0x08000000，最大也是0x0008000，中间的Size就是两者实际的大小，这两个一般是不一样大的，一般来讲，执行区域的大小是要小于加载区域的大小的，因为RW section在运行的时候会被复制到内部SRAM中去，比如说全局变量就属于这一部分，我们可以定义一个较大的数组让，后再main.c中更改一下其中的数据然后重新编译，应该就会发现执行区域和加载区域大小发生了变化，必去我们定义一个大小为10字节的全局数组：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529213119774.png" alt="image-20230529213119774" style="zoom: 50%;" />

<p>然后我们用执行域大小减去加载域大小，会发现值为0xc，其实已经不仅仅是10字节了，这里就是12个字节，具体还有什么就触及知识盲区了，后边知道了再补充吧。但是我们发现在MDK输出信息窗口的RW-data的大小为12字节，其实这里<strong>执行域大小-加载域大小应该就是等于RW-data</strong>的大小，因为这一部分会被复制到SRAM运行。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529213416563.png" alt="image-20230529213416563" style="zoom:50%;" />

<ul>
<li>（2）最后两部分</li>
</ul>
<p>例如，从上面的表中我们可以看到i.LED_GPIO_Config节区存储在内部FLASH的0x080002c4地址，大小为0x00000060，类型为Code，属性为RO。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529210432888.png" alt="image-20230529210432888" style="zoom:50%;" />

<p>而程序的STACK节区(栈空间)存储在SRAM的0x20000000地址，大小为0x00000400，类型为Zero，属性为RW（即RW-data）:</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529210513865.png" alt="image-20230529210513865" style="zoom:45%;" />

<h4 id="4-3-5-映像组件大小"><a href="#4-3-5-映像组件大小" class="headerlink" title="4.3.5 映像组件大小"></a><font size=3>4.3.5 映像组件大小</font></h4><p>map文件的最后一部分是包含映像组件大小的信息(<strong>Image component sizes</strong>)，这也是最常查询的内容：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">// 映像组件大小部分(流水灯.map文件)</span><br><span class="line">Image component sizes</span><br><span class="line"></span><br><span class="line">      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name</span><br><span class="line"></span><br><span class="line">        96          6          0          0          0        658   bsp_led.o</span><br><span class="line">         0          0          0          0          0       4524   core_cm3.o</span><br><span class="line">       278          8          0          0          0       1779   main.o</span><br><span class="line">        36          8        304          0       1024        972   startup_stm32f10x_hd.o</span><br><span class="line">       282          0          0          0          0       2887   stm32f10x_gpio.o</span><br><span class="line">        26          0          0          0          0       5038   stm32f10x_it.o</span><br><span class="line">        32          6          0          0          0        701   stm32f10x_rcc.o</span><br><span class="line">       328         28          0          0          0     214261   system_stm32f10x.o</span><br><span class="line">    ----------------------------------------------------------------------</span><br><span class="line">      1084         56        320          0       1024     230820   Object Totals</span><br><span class="line">         0          0         16          0          0          0   (incl. Generated)</span><br><span class="line">         6          0          0          0          0          0   (incl. Padding)</span><br><span class="line">// 中间部分省略</span><br><span class="line">==============================================================================</span><br><span class="line">      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   </span><br><span class="line"></span><br><span class="line">      1172         72        320          0       1024     230312   Grand Totals</span><br><span class="line">      1172         72        320          0       1024     230312   ELF Image Totals</span><br><span class="line">      1172         72        320          0          0          0   ROM Totals</span><br><span class="line">==============================================================================</span><br><span class="line">    Total RO  Size (Code + RO Data)                 1492 (   1.46kB)</span><br><span class="line">    Total RW  Size (RW Data + ZI Data)              1024 (   1.00kB)</span><br><span class="line">    Total ROM Size (Code + RO Data + RW Data)       1492 (   1.46kB)</span><br><span class="line">==============================================================================</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>这部分包含了各个使用到的*.o文件的空间汇总信息、整个工程的空间汇总信息以及占用不同类型存储器的空间汇总信息，它们分类描述了具体占据的Code、RO-data、RW-data及ZI-data的大小，并根据这些大小统计出占据的ROM总空间。我们仅来看一看分析<strong>最后两部分</strong>信息：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529210631552.png" alt="image-20230529210631552" style="zoom:45%;" />

<p>如Grand Totals一项，它表示整个代码占据的所有空间信息，其中Code类型的数据大小为1172字节，这部分包含了72字节的指令数据(inc .data)已算在内，另外RO-data占320字节，RW-data占0字节，ZI-data占1024字节。在它的下面两行有一项ROM Totals信息，它列出了各个段所占据的ROM空间，除了ZI-data不占ROM空间外，其余项都与Grand Totals中相等(RW-data也占据ROM空间，只是本工程中没有RW-data类型的数据而已)。</p>
<p>最后一部分列出了只读数据(RO)、可读写数据(RW)及占据的ROM大小。其中只读数据大小为1492字节，它包含Code段及RO-data段; 可读写数据大小为1024字节，它包含RW-data及ZI-data段；占据的ROM大小为1492字节，它除了Code段和RO-data段，还包含了运行时需要从ROM加载到RAM的RW-data数据（本工程中RW-data数据为0字节）。</p>
<h4 id="4-3-6-总结"><a href="#4-3-6-总结" class="headerlink" title="4.3.6 总结"></a><font size=3>4.3.6 总结</font></h4><p>综合整个map文件的信息，可以分析出，当程序下载到STM32的内部FLASH时，需要使用的内部FLASH是从0x0800 0000地址开始的大小为1492字节的空间；当程序运行时，需要使用的内部SRAM是从0x20000000地址开始的大小为1024字节的空间。</p>
<p>粗略一看，发现这个小程序竟然需要1024字节的SRAM，但仔细分析map文件后，可了解到这1024字节都是STACK节区的空间(即栈空间)，栈空间大小是在启动文件中定义的，这1024字节是默认值(0x00000400)。它是提供给C语言程序局部变量申请使用的空间，若我们确认自己的应用程序不需要这么大的栈，完全可以修改启动文件，把它改小一点，查看前面讲解的htm静态调用图文件可了解静态的栈调用情况，可以用它作为参考。</p>
<h1 id="二、SCT分散加载文件"><a href="#二、SCT分散加载文件" class="headerlink" title="二、SCT分散加载文件"></a><font size=3>二、SCT分散加载文件</font></h1><h2 id="1-sct分散加载文件简介"><a href="#1-sct分散加载文件简介" class="headerlink" title="1. sct分散加载文件简介"></a><font size=3>1. sct分散加载文件简介</font></h2><p>当工程按默认配置构建时，MDK会根据我们选择的芯片型号，获知芯片的内部FLASH及内部SRAM存储器概况，生成一个以工程名命名的后缀为*.sct的分散加载文件(Linker Control File，scatter loading)，<strong>链接器根据该文件的配置分配各个节区地址</strong>，生成分散加载代码，因此我们通过修改该文件可以定制具体节区的存储位置。例如，我们可以设置源文件中定义的所有变量自动按地址分配到外部SRAM，这样就不需要再使用关键字“__attribute__”按具体地址来指定了。</p>
<p>利用它还可以控制代码的加载区与执行区的位置，例如可以把程序代码存储到单位容量价格便宜的NAND-FLASH中，但在NAND-FLASH中的代码是不能像内部FLASH的代码那样直接提供给内核运行的，这时可通过修改分散加载文件，把代码加载区设定为NAND-FLASH的程序位置，而程序的执行区设定为SRAM中的位置，这样链接器就会生成一个配套的分散加载代码，该代码会把NAND-FLASH中的代码加载到SRAM中，内核再从SRAM中运行主体代码，大部分运行Linux系统的代码都是这样加载的。</p>
<h2 id="2-分散加载文件的格式"><a href="#2-分散加载文件的格式" class="headerlink" title="2. 分散加载文件的格式"></a><font size=3>2. 分散加载文件的格式</font></h2><h3 id="2-1-格式说明"><a href="#2-1-格式说明" class="headerlink" title="2.1 格式说明"></a><font size=3>2.1 格式说明</font></h3><p>下面先来看看MDK默认使用的sct文件，在Output目录下可找到“流水灯.sct”：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">// 默认的分散加载文件内容(“流水灯.sct”)</span><br><span class="line">; *************************************************************</span><br><span class="line">; *** Scatter-Loading Description File generated by uVision ***</span><br><span class="line">; *************************************************************</span><br><span class="line"></span><br><span class="line">LR_IROM1 0x08000000 0x00080000  &#123;    ; load region size_region 加载域，基地址 空间大小</span><br><span class="line">  ER_IROM1 0x08000000 0x00080000  &#123;  ; load address = execution address 载地址 = 执行地址</span><br><span class="line">   *.o (RESET, +First)</span><br><span class="line">   *(InRoot$$Sections)</span><br><span class="line">   .ANY (+RO)</span><br><span class="line">   .ANY (+XO)</span><br><span class="line">  &#125;</span><br><span class="line">  RW_IRAM1 0x20000000 0x00010000  &#123;  ; RW data 可读写数据</span><br><span class="line">   .ANY (+RW +ZI)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在默认的sct文件配置中仅分配了Code、RO-data、RW-data及ZI-data这些大区域的地址，链接时各个节区(函数、变量等)直接根据属性排列到具体的地址空间。</p>
<p>sct文件中主要包含描述加载域及执行域的部分，一个文件中可包含有多个加载域，而一个加载域可由多个部分的执行域组成。同 等级的域之间使用花括号“{ }”分隔开，最外层的是加载域，第二层“{ }”内的是执行域，其整体结构如下：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image451.jpeg" alt="分散加载文件的整体结构" style="zoom:50%;" />

<h3 id="2-2-加载域"><a href="#2-2-加载域" class="headerlink" title="2.2 加载域"></a><font size=3>2.2 加载域</font></h3><p>sct文件的加载域格式如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">//方括号中的为选填内容</span><br><span class="line">加载域名 (基地址 | (&quot;+&quot; 地址偏移)) [属性列表] [最大容量]</span><br><span class="line">&quot;&#123;&quot;</span><br><span class="line">   执行区域描述+</span><br><span class="line">&quot;&#125;&quot;</span><br></pre></td></tr></table></figure>

<p>配合前面的分散加载文件内容，各部分介绍如下：</p>
<ul>
<li>加载域名：名称，在map文件中的描述会使用该名称来标识空间。如本例中只有一个加载域，该域名为LR_IROM1。</li>
<li>基地址+地址偏移：这部分说明了本加载域的基地址，可以使用+号连接一个地址偏移，算进基地址中， 整个加载域以它们的结果为基地址。如本例中的加载域基地址为0x08000000，刚好是STM32内部FLASH的基地址。</li>
<li>属性列表：属性列表说明了加载域的是否为绝对地址、N字节对齐等属性，该配置是可选的。本例中没有描述加载域的属性。</li>
<li>最大容量：最大容量说明了这个加载域可使用的最大空间，该配置也是可选的，如果加上这个配置后， 当链接器发现工程要分配到该区域的空间比容量还大，它会在工程构建过程给出提示。本例中的加载域最大容量为0x00080000，即512KB，正是本型号STM32内部FLASH的空间大小，比如我们要是定义一个全局变量，一下子超过了512KB，空间不足的时候，编译器就会报错。</li>
</ul>
<h3 id="2-3-执行域"><a href="#2-3-执行域" class="headerlink" title="2.3 执行域"></a><font size=3>2.3 执行域</font></h3><p>sct文件的执行域格式：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">//方括号中的为选填内容</span><br><span class="line">执行域名 (基地址 | &quot;+&quot; 地址偏移) [属性列表] [最大容量 ]</span><br><span class="line">&quot;&#123;&quot;</span><br><span class="line">   输入节区描述</span><br><span class="line">&quot;&#125;&quot;</span><br></pre></td></tr></table></figure>

<p>执行域的格式与加载域是类似的，区别只是输入节区的描述有所不同，在上边流水灯.sct例子中包含了ER_IROM1及RW_IRAM两个执行域，它们分别对应描述了STM32的 内部FLASH及内部SRAM的基地址及空间大小。而它们内部的“输入节区描述”说明了哪些节区要存储到这些空间，链接器会根据它来处理编排这些节区。</p>
<h3 id="2-4-输入节区描述"><a href="#2-4-输入节区描述" class="headerlink" title="2.4 输入节区描述"></a><font size=3>2.4 输入节区描述</font></h3><p>配合加载域及执行域的配置，在相应的域配置“输入节区描述”即可控制该节区存储到域中，其格式如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">//除模块选择样式部分外，其余部分都可选选填</span><br><span class="line">模块选择样式&quot;(&quot;输入节区样式&quot;,&quot;&quot;+&quot;输入节区属性&quot;)&quot;</span><br><span class="line">模块选择样式&quot;(&quot;输入节区样式&quot;,&quot;&quot;+&quot;节区特性&quot;)&quot;</span><br><span class="line"></span><br><span class="line">模块选择样式&quot;(&quot;输入符号样式&quot;,&quot;&quot;+&quot;节区特性&quot;)&quot;</span><br><span class="line">模块选择样式&quot;(&quot;输入符号样式&quot;,&quot;&quot;+&quot;输入节区属性&quot;)&quot;</span><br></pre></td></tr></table></figure>

<p>配合前面流水灯.sct中的分散加载文件内容，各部分介绍如下：</p>
<ul>
<li><p>模块选择样式：模块选择样式可用于选择o及lib目标文件作为输入节区，它可以直接使用目标文件名或“*”通配符， 也可以使用“.ANY”。例如，使用语句“bsp_led.o”可以选择bsp_led.o文件，使用语句“*.o”可以选择所有o文件，使用“*.lib”可以选择所有lib文件，使用“*”或“.ANY”可以选择所有的o文件及lib文件。其中“.ANY”选择语句的优先级是最低的，所有其它选择语句选择完剩下的数据才会被“.ANY”语句选中。</p>
</li>
<li><p>输入节区样式：我们知道在目标文件中会包含多个节区或符号，通过输入节区样式可以选择要控制的节区。示例文件中“(RESET，+First)”语句的RESET就是输入节区样式，它选择了名为RESET的节区，并使用后面介绍的节区特性控制字“+First”表示它要存储到本区域的第一个地址。示例文件中的“*(InRoot$$Sections)”是一个链接器支持的特殊选择符号，它可以选择所有HAL库里要求存储到root区域的节区，如__main.o、__scatter*.o等内容。</p>
</li>
<li><p>输入符号样式：同样地，使用输入符号样式可以选择要控制的符号，符号样式需要使用“:gdef:”来修饰。 例如可以使用“*(:gdef:Value_Test)”来控制选择符号“Value_Test”。</p>
</li>
<li><p>输入节区属性：通过在模块选择样式后面加入输入节区属性，可以选择样式中不同的内容，每个节区属性描述符前要写一个“+”号， 使用空格或“，”号分隔开。</p>
</li>
</ul>
<details class="folding-tag" blue><summary> 可以使用的节区属性描述符 </summary>
              <div class='content'>
              <table><thead><tr><th>节区属性描述符</th><th>说明</th></tr></thead><tbody><tr><td>RO-CODE及CODE</td><td>只读代码段</td></tr><tr><td>RO-DATA及CONST</td><td>只读数据段</td></tr><tr><td>RO及TEXT</td><td>包括RO-CODE及RO-DATA</td></tr><tr><td>RW-DATA</td><td>可读写数据段</td></tr><tr><td>RW-CODE</td><td>可读写代码段</td></tr><tr><td>RW及DATA</td><td>包括RW-DATA及RW-CODE</td></tr><tr><td>ZI及BSS</td><td>初始化为0的可读写数据段</td></tr><tr><td>XO</td><td>只可执行的区域</td></tr><tr><td>ENTRY</td><td>节区的入口点</td></tr></tbody></table><p>例如，示例文件中使用“.ANY(+RO)”选择剩余所有节区RO属性的内容都分配到执行域ER_IROM1中，使用“.ANY(+RW +ZI)”选择剩余所有节区RW及ZI属性的内容都分配到执行域RW_IRAM1中。</p>
              </div>
            </details>

<ul>
<li>节区特性：节区特性可以使用“+FIRST”或“+LAST”选项配置它要存储到的位置，FIRST存储到区域的头部，LAST存储到尾部。 通常重要的节区会放在头部，比如中断向量表，而CheckSum(校验和)之类的数据会放在尾部。例如流水灯.sct文件中使用“(RESET,+First)”选择了RESET节区，并要求把它放置到本区域第一个位置，而RESET是工程启动代码中定义的向量表，该向量表中定义的堆栈顶和复位向量指针必须要存储在内部FLASH的前两个地址，这样STM32才能正常启动，所以必须使用FIRST控制它们存储到首地址。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">; Vector Table Mapped to Address 0 at Reset</span><br><span class="line">                AREA    RESET, DATA, READONLY</span><br><span class="line">                EXPORT  __Vectors</span><br><span class="line">                EXPORT  __Vectors_End</span><br><span class="line">                EXPORT  __Vectors_Size</span><br><span class="line"></span><br><span class="line">__Vectors       DCD     __initial_sp               ; Top of Stack</span><br><span class="line">                DCD     Reset_Handler              ; Reset Handler</span><br></pre></td></tr></table></figure>

<p>总的来说，我们的sct示例文件配置如下：程序的加载域为内部FLASH的0x08000000，最大空间为0x00080000；程序的执行基地址与加载基地址相同，其中RESET节区定义的向量表要存储在内部FLASH的首地址，且所有o文件及lib文件的RO属性内容都存储在内部FLASH中；程序执行时RW及ZI区域都存储在以0x20000000为基地址，大小为0x00010000的空间(64KB)，这部分正好是STM32内部主SRAM的大小。</p>
<p>链接器根据sct文件链接，链接后各个节区、符号的具体地址信息可以在map文件中查看。需要注意，当有多个执行域的时候，STM32在分配变量的时候会优先选择容量较大的执行域进行分配，除非我们直接指定了某些文件必须在某个执行域。</p>
<h2 id="3-通过MDK配置选项来修改sct文件"><a href="#3-通过MDK配置选项来修改sct文件" class="headerlink" title="3. 通过MDK配置选项来修改sct文件"></a><font size=3>3. 通过MDK配置选项来修改sct文件</font></h2><p>了解sct文件的格式后，可以手动编辑该文件控制整个工程的分散加载配置，但sct文件格式比较复杂，所以MDK提供了相应的配置选项可以方便地修改该文件，这些选项配置能满足基本的使用需求。</p>
<h3 id="3-1-选择sct文件的产生方式"><a href="#3-1-选择sct文件的产生方式" class="headerlink" title="3.1 选择sct文件的产生方式"></a><font size=3>3.1 选择sct文件的产生方式</font></h3><p>首先需要选择sct文件产生的方式，选择使用MDK生成还是使用用户自定义的sct文件。在MDK的“【Options for Target】&rarr;【Linker】&rarr;【Use Memory Layout from Target Dialog】”选项即可配置该选择：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416150518915.png" alt="image-20230416150518915" style="zoom:33%;" />

<p>该选项为“是否使用Target对话框中的存储器分布配置”，勾选后，它会根据“Options for Target”对话框中的选项生成sct文件，这种情况下，即使我们手动打开它生成的sct文件编辑也是无效的，因为每次构建工程的时候，MDK都会生成新的sct文件覆盖旧文件。该选项在MDK中是默认勾选的，若希望MDK使用我们手动编辑的sct文件构建工程，需要取消勾选，并通过Scatter File框中指定sct文件的路径：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416150619026.png" alt="image-20230416150619026" style="zoom:33%;" />

<h3 id="3-2-通过Target对话框控制存储器分配"><a href="#3-2-通过Target对话框控制存储器分配" class="headerlink" title="3.2 通过Target对话框控制存储器分配"></a><font size=3>3.2 通过Target对话框控制存储器分配</font></h3><p>若我们在Linker中勾选了“使用Target对话框的存储器布局”选项，那么“Options for Target”对话框中的存储器配置就生效了。主要配置是在Device标签页中选择芯片的类型，设定芯片基本的内部存储器信息以及在Target标签页中细化具体的 存储器配置(包括外部存储器)：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416150742032.png" alt="image-20230416150742032" style="zoom:33%;" />

<p>图中Device标签页中选定了芯片的型号为STM32F103ZE，选中后，在Target标签页中的存储器信息会根据芯片更新。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image491.jpeg" alt="Target对话框中的存储器分配" style="zoom: 45%;" />

<p>在Target标签页中存储器信息分成只读存储器(Read&#x2F;Only Memory Areas)和可读写存储器(Read&#x2F;Write Memory Areas)两类，即ROM和RAM，而且它们又细分成了片外存储器(off-chip)和片内存储器(on-chip)两类。</p>
<p>例如，由于我们已经选定了芯片的型号，MDK会自动根据芯片型号填充片内的ROM及RAM信息，其中的IROM1起始地址为0x80000000，大小为0x80000，正是该STM32型号的内部FLASH地址及大小；而IRAM1起始地址为0x20000000，大小为0x10000，正是该STM32内部主SRAM的地址及大小。图中的IROM1及IRAM1前面都打上了勾，表示这个配置信息会被采用，若取消勾选，则该存储配置信息是不会被使用的。</p>
<p>在某些芯片，会有多个内部SRAM空间，如STM32F429系列。它会在标签页中的IRAM2一栏默认也填写了配置信息，设置STM32F4系列特有的内部高速SRAM(被称为CCM)。</p>
<p>而如果希望设置外部SRAM空间，可以把外部SRAM的信息写到对话框里“off-chip”的“RAM1”配置中。</p>
<p>下面我们尝试修改Target标签页中的这些存储信息，例如，把STM32内部的SRAM分成两等份，按照下图中的配置，把IRAM1的基地址设置为0x20000000，大小改为0x8000，把IRAM2的基地址设置为0x20008000，大小为0x8000：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230416151336450.png" alt="image-20230416151336450" style="zoom:33%;" />

<p>然后编译工程， 查看到工程的sct文件如下所示：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">; *************************************************************</span><br><span class="line">; *** Scatter-Loading Description File generated by uVision ***</span><br><span class="line">; *************************************************************</span><br><span class="line"></span><br><span class="line">LR_IROM1 0x08000000 0x00080000  &#123;    ; load region size_region</span><br><span class="line">  ER_IROM1 0x08000000 0x00080000  &#123;  ; load address = execution address</span><br><span class="line">   *.o (RESET, +First)</span><br><span class="line">   *(InRoot$$Sections)</span><br><span class="line">   .ANY (+RO)</span><br><span class="line">   .ANY (+XO)</span><br><span class="line">  &#125;</span><br><span class="line">  RW_IRAM1 0x20000000 0x00008000  &#123;  ; RW data</span><br><span class="line">   .ANY (+RW +ZI)</span><br><span class="line">  &#125;</span><br><span class="line">  RW_IRAM2 0x20008000 0x00008000  &#123;</span><br><span class="line">   .ANY (+RW +ZI)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>虽然修改后IRAM1和IRAM2加起来还是原来的内部SRAM空间，但它演示了对Target选项的修改是如何影响sct文件的，我们也可以尝试其它配置，观察sct文件，以学习sct文件的语法。可以发现，sct文件根据Target标签页做出了相应的改变，除了这种修改外，在Target标签页上还控制同时使用IRAM1和IRAM2、加入外部RAM(如外接的SRAM)，外部FLASH等。当RW_IRAM1空间用完后，会自动使用RW_IRAM2。</p>
<h3 id="3-3-控制文件分配到指定的存储空间"><a href="#3-3-控制文件分配到指定的存储空间" class="headerlink" title="3.3 控制文件分配到指定的存储空间"></a><font size=3>3.3 控制文件分配到指定的存储空间</font></h3><h4 id="3-3-1-操作步骤"><a href="#3-3-1-操作步骤" class="headerlink" title="3.3.1 操作步骤"></a><font size=3>3.3.1 操作步骤</font></h4><p>设定好存储器的信息后，可以控制各个源文件定制到哪个部分存储器，在MDK的工程文件栏中，选中要配置的文件，右键，并在弹出的菜单中选择“Options for File xxxx”即可弹出一个文件配置对话框，在该对话框中进行存储器定制，如下图，使用右键打开文件配置并把它的RW区配置成使用IRAM2：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image511.jpeg" alt="图 40‑52 使用右键打开文件配置并把它的RW区配置成使用IRAM2" style="zoom: 50%;" />

<p>在弹出的对话框中有一个“Memory Assignment”区域(存储器分配)，在该区域中可以针对文件的各种属性内容进行分配，如Code&#x2F;Const内容(RO)、Zero Initialized Data内容(ZI-data)以及Other Data内容(RW-data)，点击下拉菜单可以找到在前面<strong>Target页面配置的IROM1、IRAM1、IRAM2等存储器</strong>。例如图中我们把这个bsp_led.c文件的Other Data属性的内容分配到了IRAM2存储器(在Target标签页中我们勾选了IRAM1及IRAM2)，当在bsp_led.c文件定义了一些RW-data内容时(如初值非0的全局变量)， 该变量将会被分配到IRAM2空间，配置完成后点击OK，然后编译工程，查看到的sct文件内容如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">; *************************************************************</span><br><span class="line">; *** Scatter-Loading Description File generated by uVision ***</span><br><span class="line">; *************************************************************</span><br><span class="line"></span><br><span class="line">LR_IROM1 0x08000000 0x00080000  &#123;    ; load region size_region</span><br><span class="line">  ER_IROM1 0x08000000 0x00080000  &#123;  ; load address = execution address</span><br><span class="line">   *.o (RESET, +First)</span><br><span class="line">   *(InRoot$$Sections)</span><br><span class="line">   .ANY (+RO)</span><br><span class="line">   .ANY (+XO)</span><br><span class="line">  &#125;</span><br><span class="line">  RW_IRAM1 0x20000000 0x00008000  &#123;  ; RW data</span><br><span class="line">   .ANY (+RW +ZI)</span><br><span class="line">  &#125;</span><br><span class="line">  RW_IRAM2 0x20008000 0x00008000  &#123;</span><br><span class="line">    bsp_led.o (+RW)</span><br><span class="line">   .ANY (+RW +ZI)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>可以看到在sct文件中的RW_IRAM2执行域中增加了一个选择bsp_led.o中RW内容的语句。类似地，我们还可以设置某些文件的代码段被存储到特定的ROM中，或者设置某些文件使用的ZI-data或RW-data存储到外部SRAM中(控制ZI-data到SDRAM时注意还需要修改启动文件设置堆栈对应的地址，原启动文件中的地址是指向内部SRAM的)。</p>
<p>虽然MDK的这些存储器配置选项很方便，但有很多高级的配置还是需要手动编写sct文件实现的，例如MDK选项中的内部ROM选项最多只可以填充两个选项位置，若想把内部ROM分成多片地址管理就无法实现了；另外MDK配置可控的最小粒度为文件，若想控制特定的节区也需要直接编辑sct文件。</p>
<p>不过这个并不能体现出我们定义的一些东西确实被分配到了RW_TRAM2。</p>
<p>【注意】这里我们要是修改了某一个c文件中数据在执行域的位置的话，会有这样的变化，文件左下角会有一个雪花的符号。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230530093355921.png" alt="image-20230530093355921" style="zoom:80%;" />

<h4 id="3-3-2-一个实例"><a href="#3-3-2-一个实例" class="headerlink" title="3.3.2 一个实例"></a><font size=3>3.3.2 一个实例</font></h4><ul>
<li>（1）我们在main.c中定一个全局数组，并在main.c中使用一下，防止被编译器优化</li>
</ul>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529223111082.png" alt="image-20230529223111082" style="zoom: 50%;" />

<ul>
<li>（2）我们编译一下，查看map文件中这个全局数组的地址（在Image Symbol Table部分）</li>
</ul>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529223325533.png" alt="image-20230529223325533" style="zoom:50%;" />

<p>可以看到这个数组是存储在0x20008000这个位置的，也就是说这个变量被定义在了RW_IRAM1区域。</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">RW_IRAM1 0x20000000 0x00008000  &#123;  ; RW data</span><br><span class="line">   .ANY (+RW +ZI)</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>（3）我们通过MDK的Target面板修改sct文件如下：</li>
</ul>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529223538076.png" alt="image-20230529223538076" style="zoom:50%;" />

<p>我们重新编译后，生成的sct文件内容如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">LR_IROM1 0x08000000 0x00080000  &#123;    ; load region size_region</span><br><span class="line">  ER_IROM1 0x08000000 0x00080000  &#123;  ; load address = execution address</span><br><span class="line">   *.o (RESET, +First)</span><br><span class="line">   *(InRoot$$Sections)</span><br><span class="line">   .ANY (+RO)</span><br><span class="line">   .ANY (+XO)</span><br><span class="line">  &#125;</span><br><span class="line">  RW_IRAM1 0x20000000 0x00008000  &#123;  ; RW data</span><br><span class="line">   .ANY (+RW +ZI)</span><br><span class="line">  &#125;</span><br><span class="line">  RW_IRAM2 0x20008000 0x00008000  &#123;</span><br><span class="line">   .ANY (+RW +ZI)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>（4）通过【main.c】&rarr;【右键】&rarr;【Options for File main.c】&rarr;【OtherData】&rarr;【IRAM2 [0x20008000-0x2000FFFF]】</li>
</ul>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529223843189.png" alt="image-20230529223843189" style="zoom:80%;" />

<p>然后我们重新编译工程，生成的sct文件如下：</p>
<figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">LR_IROM1 0x08000000 0x00080000  &#123;    ; load region size_region</span><br><span class="line">  ER_IROM1 0x08000000 0x00080000  &#123;  ; load address = execution address</span><br><span class="line">   *.o (RESET, +First)</span><br><span class="line">   *(InRoot$$Sections)</span><br><span class="line">   .ANY (+RO)</span><br><span class="line">   .ANY (+XO)</span><br><span class="line">  &#125;</span><br><span class="line">  RW_IRAM1 0x20000000 0x00008000  &#123;  ; RW data</span><br><span class="line">   .ANY (+RW +ZI)</span><br><span class="line">  &#125;</span><br><span class="line">  RW_IRAM2 0x20008000 0x00008000  &#123;</span><br><span class="line">    main.o (+RW)</span><br><span class="line">   .ANY (+RW +ZI)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我们会发现RW_IRAM2多了一个  main.o (+RW)。</p>
<ul>
<li>（5）查看map文件，找到test数组的定义地址：</li>
</ul>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV16-STM32%E5%BC%80%E5%8F%91/LV16-06-MDK-02-%E5%B7%A5%E7%A8%8B%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B/img/image-20230529224055149.png" alt="image-20230529224055149" style="zoom:50%;" />

<p>我们发现，这个数组已经被定义到0x20008000为起始的区域中了。</p>

    </div>

    
    
    

    <footer class="post-footer">




    <div>
        
            <div style="text-align:center;color: #ccc;font-size:14px;">
            ----------本文结束
            <i class="fas fa-fan fa-spin" style="color: #FF1493; font-size: 1rem"></i>
            感谢您的阅读----------
            </div>
        
    </div>





  
  <div class="my_post_copyright"> 
    <p><span>文章标题:</span><a href="/post/e1abea0c.html">LV16-06-MDK-02-工程文件类型</a></p>
    <p><span>文章作者:</span><a href="/" title="欢迎访问 《苏木》 的学习笔记">苏木</a></p>
    <p><span>发布时间:</span>2023年06月04日 - 22:06</p>
    <p><span>最后更新:</span>2025年06月14日 - 00:25</p>
    <p><span>原始链接:</span><a href="/post/e1abea0c.html" title="LV16-06-MDK-02-工程文件类型">https://sumumm.github.io/post/e1abea0c.html</a></p>
    <p><span>许可协议:</span><i class="fab fa-creative-commons"></i> <a rel="license" href= "https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p>  
  </div>
  


          <div class="post-tags">
              <a href="/tags/LV16-STM32%E5%BC%80%E5%8F%91/" rel="tag"><i class="fa fa-tag"></i> LV16-STM32开发</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/post/4329ee27.html" rel="prev" title="LV16-06-MDK-03-SCT文件应用">
                  <i class="fa fa-angle-left"></i> LV16-06-MDK-03-SCT文件应用
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/post/ace90973.html" rel="next" title="LV16-06-MDK-01-程序与编译">
                  LV16-06-MDK-01-程序与编译 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 2017 – 
    <span itemprop="copyrightYear">2025</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">苏木</span>
  </div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
      <span>站点总字数：</span>
    <span title="站点总字数">3.7m</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
      <span>站点阅读时长 &asymp;</span>
    <span title="站点阅读时长">225:26</span>
  </span>
</div>




    <span id="sitetime"></span>
    <script defer language=javascript>
        function siteTime()
        {
            window.setTimeout("siteTime()", 1000);
            var seconds = 1000;
            var minutes = seconds * 60;
            var hours = minutes * 60;
            var days = hours * 24;
            var years = days * 365;
            var today = new Date();
            var todayYear = today.getFullYear();
            var todayMonth = today.getMonth()+1;
            var todayDate = today.getDate();
            var todayHour = today.getHours();
            var todayMinute = today.getMinutes();
            var todaySecond = today.getSeconds();
            /*==================================================
            Date.UTC() -- 返回date对象距世界标准时间(UTC)1970年1月1日午夜之间的毫秒数(时间戳)
            year        - 作为date对象的年份，为4位年份值
            month       - 0-11之间的整数，做为date对象的月份
            day         - 1-31之间的整数，做为date对象的天数
            hours       - 0(午夜24点)-23之间的整数，做为date对象的小时数
            minutes     - 0-59之间的整数，做为date对象的分钟数
            seconds     - 0-59之间的整数，做为date对象的秒数
            microseconds - 0-999之间的整数，做为date对象的毫秒数
            ==================================================*/
            var t1 = Date.UTC(2017, 
                              5, 
                              19, 
                              0, 
                              0, 
                              0); //北京时间
            var t2 = Date.UTC(todayYear,todayMonth,todayDate,todayHour,todayMinute,todaySecond);
            var diff = t2-t1;
            var diffYears = Math.floor(diff/years);
            var diffDays = Math.floor((diff/days)-diffYears*365);
            var diffHours = Math.floor((diff-(diffYears*365+diffDays)*days)/hours);
            var diffMinutes = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours)/minutes);
            var diffSeconds = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours-diffMinutes*minutes)/seconds);
            document.getElementById("sitetime").innerHTML="已在这里 "+diffYears+" 年 "+diffDays+" 天 "+diffHours+" 小时 "+diffMinutes+" 分钟 "+diffSeconds+" 秒";
        }
        siteTime();
    </script>



    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.umd.js" integrity="sha256-ytMJGN3toR+a84u7g7NuHm91VIR06Q41kMWDr2pq7Zo=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.16.0/lozad.min.js" integrity="sha256-mOFREFhqmHeQbXpK2lp4nA3qooVgACfh88fpJftLBbc=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>




  <script src="/js/third-party/fancybox.js"></script>

  <script src="/js/third-party/pace.js"></script>


  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>


 
        <div id="click-show-text"
            data-mobile = false
            data-text = 富强,民主,文明,和谐,自由,平等,公正,法制,爱国,敬业,诚信,友善
            data-fontsize = 15px
            data-random= false>
        </div>
       

      
        <script async src=https://cdn.jsdelivr.net/npm/hexo-next-mouse-effect@latest/click/showText.js></script>
      

      
    




    <script async src="/js/fancybox_param.js"></script>





<!-- APlayer本体 -->



</body>
</html>
